导致自动生成检查错误的函数 RcppExports.R
function leading to check error in automatically generated RcppExports.R
我正在使用 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)
恭喜,您已经体验了 R 3.4.0 中添加的 Section 5.4: Registering native routines 要求。该要求强制包含一个 src/init.c
文件,该文件注册了每个 C++ 函数及其参数。因此,Rcpp 0.12.11 在 RcppExports.cpp
中生成了这个文件。同时,这个问题所基于的 RcppExports.R
文件的上下文取决于用户是否适当地设置了 useDynLib(pkgname, .registration=TRUE)
或 useDynLib(pkgname)
,后者并不理想,因为它没有利用接下来讨论的 Rcpp 0.12.11 中引入的新选项。
由于 CRAN 政策的这种转变,Rcpp 1 属性的创建者 JJ Allaire 受到启发,提出了 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:]]+")
不得不删除它并选择手动指定应导出哪些函数或变量。
更多详情,不妨看看介绍该功能的GitHubPR:
https://github.com/RcppCore/Rcpp/pull/694
1:有关属性的更多信息,请参阅我的历史记录post:http://thecoatlessprofessor.com/programming/rcpp/to-rcpp-attributes-and-beyond-from-inline/
我正在使用 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)
恭喜,您已经体验了 R 3.4.0 中添加的 Section 5.4: Registering native routines 要求。该要求强制包含一个 src/init.c
文件,该文件注册了每个 C++ 函数及其参数。因此,Rcpp 0.12.11 在 RcppExports.cpp
中生成了这个文件。同时,这个问题所基于的 RcppExports.R
文件的上下文取决于用户是否适当地设置了 useDynLib(pkgname, .registration=TRUE)
或 useDynLib(pkgname)
,后者并不理想,因为它没有利用接下来讨论的 Rcpp 0.12.11 中引入的新选项。
由于 CRAN 政策的这种转变,Rcpp 1 属性的创建者 JJ Allaire 受到启发,提出了 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:]]+")
不得不删除它并选择手动指定应导出哪些函数或变量。
更多详情,不妨看看介绍该功能的GitHubPR:
https://github.com/RcppCore/Rcpp/pull/694
1:有关属性的更多信息,请参阅我的历史记录post:http://thecoatlessprofessor.com/programming/rcpp/to-rcpp-attributes-and-beyond-from-inline/