.Call 的 PACKAGE 参数如何工作?

How does the PACKAGE argument to .Call work?

.Call 似乎没有很好的记录; ?.Call给出了PACKAGE参数的解释:

PACKAGE: if supplied, confine the search for a character string .NAME to the DLL given by this argument (plus the conventional extension, ‘.so’, ‘.dll’, ...).

This argument follows ... and so its name cannot be abbreviated.

This is intended to add safety for packages, which can ensure by using this argument that no other package can override their external symbols, and also speeds up the search (see ‘Note’).

并在注释中:

If one of these functions is to be used frequently, do specify PACKAGE (to confine the search to a single DLL) or pass .NAME as one of the native symbol objects. Searching for symbols can take a long time, especially when many namespaces are loaded.

You may see PACKAGE = "base" for symbols linked into R. Do not use this in your own code: such symbols are not part of the API and may be changed without warning.

PACKAGE = "" used to be accepted (but was undocumented): it is now an error.

但是没有使用示例。

尚不清楚 PACKAGE 论点是如何运作的。例如,在回答 问题时,我认为以下应该有效,但它没有:

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

相反,这个有效:

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

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

这看起来很简单,但很少能找到这个参数的用法; none 我发现的来源不仅仅只是提及 (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

C_BinCount是class"NativeSymbolInfo"的对象,而不是命名C级函数的字符串,因此PACKAGE("confine(s) the search for a character string .NAME")不相关. C_BinCount 在图形包 NAMESPACE.

中的 useDynLib() 中被提及而成为一个符号

作为 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