最近我一直在試用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