2011-12-07 51 views
3

我試圖編譯SHLIB下面的函數(保存爲foo.cpp):使用SHLIB編譯和負載獨立RCPP功能

#include <Rcpp.h> 

RcppExport SEXP foo(SEXP x, SEXP y){ 
     Rcpp::NumericVector xx(x), yy(y) ; 
     int n = xx.size() ; 
     Rcpp::NumericVector res(n) ; 
     double x_ = 0.0, y_ = 0.0 ; 
     for(int i=0; i<n; i++){ 
       x_ = xx[i] ; 
       y_ = yy[i] ; 
       if(x_ < y_){ 
         res[i] = x_ * x_ ; 
       } else { 
         res[i] = -(y_ * y_) ; 
       } 
     } 
     return res ; 
} 

我嘗試

$ R CMD SHLIB foo.cpp 
/opt/local/bin/g++-mp-4.4 -I/opt/local/lib/R/include -I/opt/local/lib/R/include/x86_64 -I/opt/local/include -fPIC -pipe -O2 -m64 -c foo.cpp -o foo.o 
foo.cpp:1:18: error: Rcpp.h: No such file or directory 
foo.cpp:3: error: 'RcppExport' does not name a type 
make: *** [foo.o] Error 1 

如何包含這個文件,這是用Rcpp編譯獨立函數的正確方法嗎?當然,我已經用install.packages('Rcpp')安裝了Rcpp。

更新: 試圖找到Rcpp.h的RI的位置得到:

> system.file("lib", "Rcpp.h", package="Rcpp") 
[1] "" 
> 

然而,

> Rcpp:::LdFlags() 
/opt/local/lib/R/library/Rcpp/lib/x86_64/libRcpp.a> 

更新2:

看着http://www.mail-archive.com/[email protected]/msg79185.html ,我試過

$ PKG_CPPFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'` \ 
>   PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'` \ 
>   R CMD SHLIB foo.cpp 
/opt/local/bin/g++-mp-4.4 -I/opt/local/lib/R/include -I/opt/local/lib/R/include/x86_64 -I/opt/local/lib/R/library/Rcpp/include -I/opt/local/include -fPIC -pipe -O2 -m64 -c foo.cpp -o foo.o 
/opt/local/bin/g++-mp-4.4 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/opt/local/lib -o foo.so foo.o /opt/local/lib/R/library/Rcpp/lib/x86_64/libRcpp.a -L/opt/local/lib/R/lib/x86_64 -lR 

它產生了foo.ofoo.so。我現在如何在R中導入?

更新3: 因此,它可以從dyn.load被加載

> dyn.load("foo.so") 
> is.loaded("foo") 
[1] TRUE 

它可以成功地稱爲爲

> .Call("foo",x=as.numeric(c(1,2,3)),y=as.numeric(c(4,5,6))) 
[1] 1 4 9 

雖然功能不是這樣可見。

> foo 
Error: object 'foo' not found 
+0

繼續搜索並閱讀文檔。對於最近的問題,請閱讀'SHLIB'的另請參見部分。 –

+0

@JoshuaUlrich,感謝downvote,但是從See See部分,你的意思是'library.dynam'? 'library.dynam(「foo」)'''library.dynam(「foo.o」)'和'library.dynam(「foo.so」)'仍然給我錯誤。 – highBandWidth

+0

你顯然沒有閱讀文檔。 ''library.dynam'說它應該只在一個包中使用,特別是'.onLoad'。在嘗試和報告「錯誤」之前,請閱讀並理解文檔。 –

回答

3

你的問題明確解決在問題2.4中。的Rcpp-FAQ

+0

現在是第2.5項 - 奇怪的是,在我的機器上(OS X),'Rcpp ::: LdFlags()'是空的。這是一個錯誤?編譯似乎很好。 –

+0

這是一個特性,請參閱Rcpp 0.11.0發行說明,或者在此處以及rcpp-devel中提出十幾個問題。但是通過'R CMD SHLIB'進行編譯仍然是一個糟糕的主意。 –

2

我發現答案是:SHLIB需要提供的文件RCPP的位置。這是可以做到

$ PKG_CPPFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'` \ 
>   PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'` \ 
>   R CMD SHLIB foo.cpp 

然後,編譯的文件可以在R上加載

> dyn.load("foo.so") 

,並在R中可以被稱爲

> .Call("foo",c(1,2,3),c(4,5,6)) 
+0

其中沒有任何與非Rcpp包不同的任何內容都將被構建和加載,並且在「編寫R擴展」中有明確記錄。這裏的所有不同之處在於您需要爲Rcpp提供'-I'和'-L'標誌 - 這就是我們推薦使用'inline'軟件包的原因。 –