2009-07-24 44 views
2

我正在創建一個R程序包,我打算提交給具有調用C語言編寫的例程的函數的CRAN。如何加載編譯的C程序在平臺無關的方式在R功能?我能夠讓我的工作包在我的基於Intel的Mac有:dyn.load在R程序包中調用C函數的便攜式使用

function(mydata) 
{ 
dyn.load(file.path(.Library,"mypkg/libs/i386",paste("mypkg", .Platform$dynlib.ext, sep=""))) 
try(
    output <- .C("myfunc_cversion", 
       in_data = as.double(mydata), 
       res_data = as.double(res), 
       PACKAGE = "mypkg") 
    ) 
    result <- as.matrix(output$res_data) 
    return(result) 
} 

的問題是調用dyn.load,我無法弄清楚如何指定的完整路徑的共享庫爲我安裝以便攜式方式包裝。

除了我應該使用的庫還有另外一個變量,還是在這種情況下比dyn.load有更好的功能?

回答

0

您需要查看library.dynam()的手冊頁。它應該允許你做你想做的事情,例如。

function(mydata) 
{ 
library.dynam("mysharedobject",package=c("mypkg")) 
try(
     output <- .C("myfunc_cversion", 
        in_data = as.double(mydata), 
        res_data = as.double(res), 
        PACKAGE = "mypkg") 
     ) 
     result <- as.matrix(output$res_data) 
     return(result) 
} 

其中mysharedobject是共享對象的文件的名稱,而不的.dll /等。所以在端。

手冊頁還建議您只在.onLoad().First.lib()函數中使用它。

HTH


http://sekhon.berkeley.edu/base/html/library.dynam.html

2

我認爲你是使它過於複雜。您可以隨時諮詢CRAN現有的1800+套餐。通常,大多數包通過.onLoad加載目標代碼(甚至可以通過NAMESPACE文件實現自動化) - 請參閱R Extensions手冊。

舉個簡單的例子,你可以看看我的digest包,用它從文件R/zzz.R(這是標準做法手冊中的建議)

.onLoad <- function(lib, pkg) { 
    library.dynam("digest", pkg, lib) 
} 

SO封裝後下加載動態庫中的所有函數可供所有R函數調用。這比爲每個函數添加一個library.dynam()更加通用(而且最重要的是,每個R會話只需要library.dynam()一次)。

R本身處理擴展名(.dll,.so,.dylib,...)和所有其他每個平臺的基本信息。我認爲沒有理由轉而採用這種方法。所以請參閱手冊以及(數字)幾百個發佈的包。


2

我發現,如果我在包中使用一個名稱空間,然後我還可以通過使用空間文件內useDynLib指令的包(如本手冊第1.6.3節描述的解決這個問題。「編寫R擴展「版本2.9.1,地址爲www.r-project.org)。

我的空間文件現在看起來像:

useDynLib(mypkg, myfunc_cversion) 
export(myfunc) 

我再修改R函數定義:

myfunc <- function(mydata) 
{ 
try(
    output <- .C(myfunc_cversion, 
       in_data = as.double(mydata), 
       res_data = as.double(res)) 
    ) 
    result <- as.matrix(output$res_data) 
    return(result) 
} 

也就是說,與周圍的C函數名和不PACKAGE說法暫無報價在撥打.C