.Call的PACKAGE参数如何工作?

Mic*_*ico 8 r internals

.Call似乎很难记录; ?.Call给出了PACKAGE论证的解释:

PACKAGE:如果提供,则将搜索字符串限制在.NAME此参数给出的DLL中(加上常规扩展名'.so','.dll',...).

该论点如下...,因此其名称不能缩写.

这是为了增加包的安全性,这可以通过使用这个参数确保没有其他包可以覆盖它们的外部符号,并且还加快了搜索速度(参见'注意').

并在注意:

如果要经常使用其中一个函数,请指定PACKAGE(将搜索限制在单个DLL中)或.NAME作为本机符号对象之一传递.搜索符号可能需要很长时间,尤其是在加载了许多名称空间时.

您可能会看到PACKAGE = "base"链接到R的符号.请勿在您自己的代码中使用此符号:此类符号不是API的一部分,可能会在没有警告的情况下进行更改.

PACKAGE = "" 过去被接受(但没有记录):现在是一个错误.

但是没有用例.

目前还不清楚这个PACKAGE论点是如何运作的.例如,在回答这个问题时,我认为以下内容应该有效,但事实并非如此:

.Call(C_BinCount, x, breaks, TRUE, TRUE, PACKAGE = "graphics")
Run Code Online (Sandbox Code Playgroud)

相反,这有效:

.Call(graphics:::C_BinCount, x, breaks, TRUE, TRUE)
Run Code Online (Sandbox Code Playgroud)

这只是因为C_BinCount未被移植?即,如果hist.default添加了内部代码PACKAGE = "graphics",这会有用吗?

这看起来很简单,但很难找到这个论点的用法; 没有的我发现源给出比通过提及以上(1,2,3,4,5)...实际工作的这方面的例子,将不胜感激(即使它只是引用在现有的包中找到的代码)

(自我遏制的目的,如果你不希望从另一个问题复制粘贴代码,这里有xbreaks):

x = runif(100000000, 2.5, 2.6)
nB <- 99
delt <- 3/nB
fuzz <- 1e-7 * c(-delt, rep.int(delt, nB))
breaks <- seq(0, 3, by = delt) + fuzz
Run Code Online (Sandbox Code Playgroud)

Mar*_*gan 10

C_BinCount是"NativeSymbolInfo"类的对象,而不是命名C级函数的字符串,因此PACKAGE("限制搜索字符串.NAME")不相关.在图形包NAMESPACE中C_BinCount提到它是一个符号.useDynLib()

作为R符号,其C_BinCount分辨率与其他符号的规则相同 - 它不是从NAMESPACE导出的,因此只能通过graphics:::C_BinCount.而且,由于这个原因,禁止强大的代码开发.由于C入口点是作为符号导入的,因此它不能用作字符串,因此.Call("C_BinCount", ...)不起作用.

使用NativeSymbolInfo对象告诉R C代码所在的位置,因此不需要通过PACKAGE再次执行此操作; 使用符号而不是字符串的选择是由包开发者做出的,我认为通常被认为是一种好的做法.在NativeSymbolInfo发明之前开发的许多包使用PACKAGE参数,如果我grep Bioconductor源树,则有4379行.Call.*PACKAGE,例如,这里.

其他信息,包括示例,在写入R扩展部分1.5.4中.

  • @MichaelChirico RE:实际的例子,如果你使用Rcpp(属性)创建一个包,生成的包装函数将使用`.Call`和`PACKAGE`参数.这是一个[最小例子](https://gist.github.com/nathan-russell/7eec0187b598622d390c28296d5c1907#file-rcpp-dot-call-r-L37-L43). (2认同)