在Windows下调试(一行一行)Rcpp生成的DLL
最近我一直在尝试使用Rcpp(内联)来生成在提供的R输入上执行各种任务的DLL.我想要能够逐行调试这些DLL中的代码,给定一组特定的R输入. (我在Windows下工作.)
为了说明,让我们考虑一个具体的例子,任何人都应该能够运行… 下面的代码是一个非常简单的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 现在,通过f0调用DLL的明显方法如下 > f0(c(-7,0.7,77)) $out1 [1] -14.0 1.4 154.0 但是我们当然也可以使用.Call命令直接通过名称来调用DLL: > .Call("file7e61645c",c(-7,77)) $out1 [1] -14.0 1.4 154.0 所以我已经达到了直接用R输入(这里是向量c(-7,77))直接调用独立DLL,并将其正确地返回给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用户对
inline包及其cxxfunction()的迷恋感到有点震惊.是的,这确实是非常有用的,它肯定已经推动了
Rcpp的进一步采用,因为它使快速的实验变得更加容易.是的,它允许我们在源中使用700个单元测试.是的,我一直使用它来演示这里的例子,在
rcpp-devel list,甚至生活在
presentations.
但这是否意味着我们应该使用它来进行每一项任务?这是否意味着它没有“成本”,如临时目录等中的随机文件名?罗曼和我在我们的文件中另有争议. 最后,动态加载的R模块的调试比较困难.在(强制性)Writing R Extensions中有一个关于它的整个部分,Doug Bates一两次发布了关于如何通过ESS和Emacs(尽管我总是忘记他发布的地方)的教程;曾经是07年3月的IIRC. 编辑2012年7月 – 7月: 这是你的一步一步: (序言:我已经使用gcc和g了很多年了,甚至当我添加-g时,我并不总是把-O2变成-O0,我真的不确定你需要这个,但是你要的是. ..)
我得到 [...] Compilation argument: /usr/lib/R/bin/R CMD SHLIB file11673f928501.cpp 2> file11673f928501.cpp.err.txt ccache g++-4.6 -I/usr/share/R/include -DNDEBUG -I"/usr/local/lib/R/site- library/Rcpp/include" -fpic -g -O0 -Wall -c file11673f928501.cpp -o file11673f928501.o g++-4.6 -shared -o file11673f928501.so file11673f928501.o -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/lib/R/lib -lR >调用例如tempdir()来查看临时目录,cd到上面使用的这个临时目录和dyn.load()上面构建的文件:
>现在通过发送中断信号暂停R(在Emacs中,从下拉菜单中选择一个简单的选项).
>返回R,调用函数:
> Presto,在我们想要的断点处的调试器中:
>现在,“只是”你的工作gdb的魔法 现在,正如我在第一次尝试中所说的那样,通过Rcpp.package.skeleton()可以为您编写的一个简单的包,所有这一切将更容易(在我看来),因为您不必处理随机的目录和文件名.但每一个到自己的… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Windows计算机从标记VLAN获取SLAAC IPv6
- windows – Minifilter驱动程序,内存映射和记事本
- Windows XP全盘加密 – 有哪些选择?
- 如何从注册表更新Windows PowerShell会话环境变量
- dll – 加载时间动态链接和运行时动态链接之间的区别
- windows-server-2008-r2 – 如何在域控制器上禁用UAC?
- 学习Windows应用商店xaml的最佳资源?
- windows-7 – 我可以在Windows 7机器上为Microsoft Surface
- Windows中的语言环境列表
- windows-server-2008 – 如果我不小心重置了计算机帐户该怎