.Call的PACKAGE参数如何工作?

时间:2016-07-18 14:49:23

标签: r internals

.Call似乎记录不清楚; ?.Call给出了PACKAGE参数的解释:

  

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

     

此参数遵循...,因此其名称不能缩写。

     

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

在注释中:

  

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

     

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

     

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

但是没有用例。

目前还不清楚PACKAGE论证是如何运作的。例如,在回答this问题时,我认为以下内容应该有效,但它没有:

.Call(C_BinCount, x, breaks, TRUE, TRUE, PACKAGE = "graphics")

相反,这有效:

.Call(graphics:::C_BinCount, x, breaks, TRUE, TRUE)

这只是因为C_BinCount未被导出吗?也就是说,如果hist.default的内部代码添加了PACKAGE = "graphics",这会有用吗?

这看起来很简单,但很难找到这个论点的用法;我找到的所有来源都不仅仅是提及(12345)......这些实际工作的例子将不胜感激(即使它只是引用现有包中的代码)

(出于自我限制的目的,如果您不想复制粘贴来自其他问题的代码,则此处为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

1 个答案:

答案 0 :(得分:10)

C_BinCount是类&#34; NativeSymbolInfo&#34;的对象,而不是命名C级函数的字符串,因此PACKAGE(&#34;限制搜索a字符串.NAME&#34;)不相关。 C_BinCount在图片包NAMESPACEuseDynLib()中被提及为符号。

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

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

其他信息(包括示例)位于“写入R扩展”部分1.5.4