我正在使用 Rcpp 0.12.11 和 R 3.4.0。
当我将 Rcpp 升级到 0.12.11 时,由 Rcpp::compileAttributes 自动生成的 R 文件 RcppExports.R 开始为我提供略有不同的函数调用
run_graph_match <- function(A, B, algorithm_params) {
# Rcpp 0.12.10
.Call('RGraphM_run_graph_match', PACKAGE = 'RGraphM', A, B, algorithm_params)
# Rcpp 0.12.11
.Call(RGraphM_run_graph_match, A, B, algorithm_params)
}
有没有简单的方法来解释更改背后的原因?
后一个函数在检查 R 包时会导致错误。例如,诸如此类的错误 符号“RGraphM_run_graph_match”不在命名空间中: .Call(RGraphM_run_graph_match, A, B, Algorithm_params)
最佳答案
恭喜您,您已经体验了Section 5.4: Registering native routines R 3.4.0 中添加了要求。该要求强制包含一个 src/init.c
文件,用于注册每个 C++ 函数及其参数。因此,Rcpp 0.12.11 在 RcppExports.cpp
内生成此文件。同时,这个问题所基于的 RcppExports.R 文件的上下文取决于用户是否正确设置了 useDynLib(pkgname, .registration=TRUE) > 或 useDynLib(pkgname)
,后者并不理想,因为它没有利用接下来讨论的 Rcpp 0.12.11 中引入的新选项。
由于 CRAN 政策的这一转变,Rcpp 属性的创建者 JJ Allaire 1 受到启发,提出了 Douglas Bates 早在 2012 年首次添加属性时提出的建议。具体来说,目标是将调用从基于字符串的调用更改为符号调用。更改背后的基本原理简单地说,当程序包加载时,符号就已存在,而每次运行函数时都必须查找字符串并将其转换为符号。因此,与过去 Rcpp 基于字符串的方法相比,符号查找在重复调用时的成本更低。
基本上,这一行:
.Call('RGraphM_run_graph_match', PACKAGE = 'RGraphM', A, B, algorithm_params)
涉及 R 在每次调用包含的 R 函数时查找符号以访问 C++ 函数。
同时,这一行:
.Call(RGraphM_run_graph_match, A, B, algorithm_params)
是对C++函数的直接调用,因为符号已经在内存中。
这些主要是 Rcpp 改变 RcppExports.R
自动生成方式背后的原因。这种方法的缺点之一是无法像以前一样全局导出所有函数。特别是,一些在其 NAMESPACE
文件中包含全局符号导出语句的用户,例如
exportPattern("^[[:alpha:]]+")
必须删除它并选择手动指定应导出哪些函数或变量。
有关更多详细信息,您不妨查看介绍此功能的 GitHub PR:
https://github.com/RcppCore/Rcpp/pull/694
1:有关属性的更多信息,请参阅我的历史帖子:http://thecoatlessprofessor.com/programming/rcpp/to-rcpp-attributes-and-beyond-from-inline/
关于r - 函数导致自动生成的 RcppExports.R 检查错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44666294/