2

我正在创建一个我打算提交给 CRAN 的 R 包,它有一个调用用 C 编写的例程的函数。如何以独立于平台的方式在 R 函数中加载编译的 C 例程?我能够使我的包在我的基于英特尔的 Mac 上工作:

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 的调用,我无法弄清楚如何以可移植的方式为我安装的包指定共享库的完整路径。

除了我应该使用的 .Library 之外,R 中是否还有另一个变量,或者在这种情况下是否有比 dyn.load 更好的功能?

4

3 回答 3

2

我发现如果我在包中使用名称空间,那么我也可以通过使用useDynLib包的 NAMESPACE 文件中的指令来解决这个问题(如手册“Writing R Extensions”版本 2.9.1 的第 1.6.3 节中所述在www.r-project.org)。

我的 NAMESPACE 文件现在看起来像:

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

于 2009-07-24T11:38:34.493 回答
1

我认为你把它弄得太复杂了。您可以随时查阅CRAN上现有的 1800 多个软件包。作为一般规则,大多数包在启动时通过 .onLoad 加载目标代码(甚至可以通过 NAMESPACE 文件自动执行)——参见 R Extensions 手册。

作为一个简单的示例,您可以查看我的摘要包,它使用文件 R/zzz.R 中的以下内容(这是手册中建议的标准方法)

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

因此,在包加载后,动态库中的所有函数都可供所有 R 函数调用。这比向每个函数添加 library.dynam() 更通用(而且在每个 R 会话中,最重要的是,您只需要 library.dynam() 一次)。

R 本身处理扩展名(.dll、.so、.dylib、...)和所有其他每个平台的细节。我认为没有理由改变这种做法。因此,请参阅手册,以及(字面上)数百个已发布的软件包。


于 2009-07-24T11:35:47.273 回答
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/.so 等的共享对象文件的名称在哪里。

手册页还建议您仅在.onLoad()or.First.lib()函数中使用它。

高温高压


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

于 2009-07-24T10:19:41.110 回答