最近我一直在试用Rcpp(内联)来生成在提供的R输入上执行各种任务的DLL。 我希望能够逐行调试这些DLL中的代码,给定一组特定的R输入。(我在Windows下工作。)在Windows下调试(逐行)Rcpp生成的DLL
为了说明这一点,让我们考虑一个具体的例子,任何人都应该能够运行......
下面的代码是一个非常简单的cxxfunction它只是双打输入向量。但请注意,还有一个额外的变量myvar
可以将值更改几次,但不会影响输出 - 已添加该变量,以便我们能够看到调试过程何时正确运行。
library(inline)
library(Rcpp)
f0 <- cxxfunction(signature(a="numeric"), plugin="Rcpp", body='
Rcpp::NumericVector xa(a);
int myvar = 19;
int na = xa.size();
myvar = 27;
Rcpp::NumericVector out1(na);
for(int i=0; i < na; i++) {
out1[i] = 2*xa[i];
myvar++;
}
myvar = 101;
return(Rcpp::List::create(_["out1"] = out1));
')
后,我们运行上面,键入命令
getLoadedDLLs()
带来了在R对话的DLL列表。最后一个上市的应该是上述过程中创建的DLL - 它有一个随机的临时名称,这在我的情况是
file7e61645c
“文件名”栏中显示cxxfunction已经把这个DLL中的位置tempdir()
,这对我来说是目前
C:/Users/TimP/AppData/Local/Temp/RtmpXuxtpa/file7e61645c.dll
现在,明显的方式来调用DLL是通过f0
,如下
> f0(c(-7,0.7,77))
$out1
[1] -14.0 1.4 154.0
但是,我们当然可以还名称使用.Call
命令直接调用DLL:
> .Call("file7e61645c",c(-7,0.7,77))
$out1
[1] -14.0 1.4 154.0
所以,我已经到达了我直接调用DLL独立与R输入(这里,向量c(-7,0.7,77)
)点,并让它回归答案正确地R.
我真正需要的,不过,是行由行调试工具(用gdb,我相信),让我观察到的myvar
值被设置为19, 27,28,29,30,最后101代码进行。以上示例是故意设置的,因此调用DLL不会告诉我们关于myvar的任何信息。
为了澄清,这里的“胜利条件”能够观察到myvar的变化(看到myvar = 19的值将是第一步!),而不添加任何其他内容到代码体中。这显然可能需要修改代码的编译方式(是否有打开调试模式的设置?),或者调用R的方式 - 但我不知道从哪里开始。如上所述,所有这些都是基于Windows的。
最后说明:在我的实验中,我实际上对cxxfunction的副本进行了一些小的修改,以便输出DLL及其内的代码接收用户定义的名称并位于用户定义的目录中比临时名称和位置。但这并不影响问题的实质。我提到这只是为了强调,如果有人给我一个微调,应该很容易改变编译设置:)
为了完整起见,在上面的原始cxxfunction调用中设置verbose = TRUE显示编译参数为下面的表格:
C:/R/R-2.13.2/bin/i386/R CMD SHLIB file7e61645c.cpp 2> file7e61645c.cpp.err.txt
g++ -I"C:/R/R-213~1.2/include" -I"C:/R/R-2.13.2/library/Rcpp/include" -O2 -Wall -c file7e61645c.cpp -o file7e61645c.o
g++ -shared -s -static-libgcc -o file7e61645c.dll tmp.def file7e61645c.o C:/R/R-2.13.2/library/Rcpp/lib/i386/libRcpp.a -LC:/R/R-213~1.2/bin/i386 -lR
我的改编版本有一个编译参数与上述相同,除了字符串“file7e61645c”是由用户选择的名字代替无处不在(如“testdll”)及有关文件复制到更加永久的位置。
预先感谢您的帮助球员:)
我不能直接帮助,但我知道德克等总是有帮助的。但他们通常在[Rcpp电子邮件列表]上做生意(http://lists.r-forge.r-project.org/mailman/listinfo/rcpp-devel) – 2012-07-05 15:15:21
已经在这方面取得了一些温和的进展,所以简短的更新。使用inline ::: compileCode(在cxxfunction中被调用)时,我发现在'R CMD SHLIB'的末尾添加'--debug'使我可以通过组合gdb和R来检查DLL内部发生了什么。HOWEVER ,这不是一个完整的解决方案,因为有些变量是不可访问的(例如'i',在'i'上的循环中);消息传来,他们被“优化了”。因此,我认为我需要在编译参数中将“-O2”替换为“-O0”......但我没有如何做到这一点的想法...... – 2012-07-05 16:18:42
我收集了很多证据,我所需要做的就是将R CMD SHLIB编译器标志从-O2更改为类似-g -O0的内容......例如请参阅https://stat.ethz.ch/pipermail/r-devel/2008-November/051390.html中的文章 - 但我缺乏关于需要指定和如何的精确声明。一些在线资源提到在'/.R/Makevars.win'创建一个文件,但是它们没有描述该文件,并且由于字母R之前的点,这不是Windows中的有效位置。 –
2012-07-05 17:22:21