问题
I am using Rcpp 0.12.11 and R 3.4.0.
When I upgraded Rcpp to 0.12.11, the automatically generated R file RcppExports.R by the Rcpp::compileAttributes started to give me slightly different function calls
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)
}
Is there an easy way to explain the reason behind the change?
The latter function leads to errors when checking the R package. For example, errors such as symbol 'RGraphM_run_graph_match' not in namespace: .Call(RGraphM_run_graph_match, A, B, algorithm_params)
回答1:
Congratulations, you've experienced the Section 5.4: Registering native routines requirement added in R 3.4.0. The requirement mandated the inclusion of a src/init.c
file that registered each C++ function and their parameters. Thus, Rcpp 0.12.11 generates this file inside of the RcppExports.cpp
. Meanwhile, the RcppExports.R
file, which is what this question is based upon, has its context being dependent on whether the user appropriately sets useDynLib(pkgname, .registration=TRUE)
or useDynLib(pkgname)
, where the later is not ideal as it does not take advantage of a new option introduced in Rcpp 0.12.11 discussed next.
As a result of this shift in CRAN policy, JJ Allaire, the creator of Attributes for Rcpp 1, was inspired to advance a suggestion made by Douglas Bates back in 2012 when attributes was first added. Specifically, the goal was to change the call from being string-based to being a symbol. The rationale behind the change is simply put that a symbol is onhand when the package loads vs. a string which has to be looked up and converted into a symbol each time the function is run. Therefore, symbol lookup is less expensive on repetitive calls when compared to the string based method of Rcpp in the past.
Basically, this line:
.Call('RGraphM_run_graph_match', PACKAGE = 'RGraphM', A, B, algorithm_params)
Involved R looking up the symbol on each call of the encompassing R function to access the C++ function.
Meanwhile, this line:
.Call(RGraphM_run_graph_match, A, B, algorithm_params)
is a direct call to the C++ function as the symbol is already in memory.
And those are primarily the reasons behind why Rcpp changed how RcppExports.R
was automatically generated. One of the downside of this approach is the inability to globally export all functions like before. In particular, some users that had in their NAMESPACE
file a global symbol export statement e.g.
exportPattern("^[[:alpha:]]+")
had to remove it and opt to manually specify what functions or variables should be exported.
For more details, you may wish to see the GitHub PR that introduced this feature:
https://github.com/RcppCore/Rcpp/pull/694
1: For more on Attributes, see my history post: http://thecoatlessprofessor.com/programming/rcpp/to-rcpp-attributes-and-beyond-from-inline/
来源:https://stackoverflow.com/questions/44666294/function-leading-to-check-error-in-automatically-generated-rcppexports-r