[R-pkg-devel] moving from C to C++ with Rcpp in R package

Dirk Eddelbuettel edd @end|ng |rom deb|@n@org
Wed Jun 1 22:18:47 CEST 2022


On 1 June 2022 at 11:03, THIOULOUSE JEAN wrote:
| Hello
| 
| I need some help to add C++ functions using Rcpp to the ade4 package.
| 
| The ade4 package (on CRAN) already contains many C functions, mainly to perform randomization tests, and we would like to replace some of these functions by C++ ones using Rcpp, as well as add more new C++ functions, using also Rcpp.
| 
| To start with, I have only one C++ function and one R wrapper function, named respectively RV.randtest and RVrandtestCpp. Both functions work fine, using sourceCpp("RVrandtestCpp.cpp") and calling it with RV.randtest in R from the command line, and I also checked that the RcppExamples package compiles without problem with my configuration. Everything is available in https://github.com/thioulouse/RVrandtest
| 
| Now, I want to integrate these two functions in the ade4 package, so I have done the following things:
| 
| - added Rcpp and RcppArmadillo to the Imports field in the DESCRIPTION file
| - added the LinkingTo field, with Rcpp and RcppArmadillo in the DESCRIPTION file
| - added importFrom("Rcpp", "sourceCpp") in the NAMESPACE file
| - added export("RV.randtest") and export("RVrandtestCpp") in the NAMESPACE file
| - added RV.randtest.Rd in the man directory and \alias{RVrandtestCpp} in ade4-internal.Rd
| - added RV.randtest.R in the R directory
| - added RVrandtestCpp.cpp in the src directory
| 
| Then I used the Rcpp compileAttributes() function to add:
| 
| - RcppExports.cpp in the src directory
| - RcppExports.R in the R directory
| 
| But when I check the modified ade4 package (with R CMD BUILD / R CMD CHECK), I get the following notes:
| 
| * checking R code for possible problems ... NOTE
| RVrandtestCpp: no visible binding for global variable
|   ‘_ade4_RVrandtestCpp’
| Undefined global functions or variables:
|   _ade4_RVrandtestCpp
| 
| And when running the examples I get the following error:
| 
| > rv1 <- RV.randtest(pca1$tab, pca2$tab, 99)
| Error in RVrandtestCpp(X, Y, nrepet) : 
|   object '_ade4_RVrandtestCpp' not found
| Calls: RV.randtest -> RVrandtestCpp
| Execution halted
| 
| So I am probably missing something, and I have the following questions:
| 
| Do I have to modify the init.c file in the src directory ? It contains the reference to all the C functions called in the ade4 package, but not the C++ function from Rcpp. Should I add it here ? I tried to do it, with no luck.
| 
| The NAMESPACE file contains this first line: 
| useDynLib(ade4, .registration = TRUE, .fixes = "C_")
| The .fixes argument is related to C function calls. Can this raise a problem for calling C++ functions ?
| 
| Why is the _ade4_RVrandtestCpp function (defined by compileAttributes() in RcppExports.cpp) not visible in RVrandtestCpp and not found at runtime ?

You most likely have an issue with the code commonly placed in src/init.c
which registers entry points.

Rcpp is rather good at autogenerating it for more standard packages
containing only C++ code.  Mixing C and C++ code is not something the package
is that well set up for.  I think I fought the same issue in the past on
packages that transitioned, or just added a C++ file or two. I don't think
there is a great solution.  I would suggest you
 - use the init.c you have from the existing package
 - create a new one-off package with the C++ functions you want to use 
 - manually carry this over to your existing init.c
 
I would generally recommend starting with Rcpp.package.skeleton("testpackage")
(or a similar name) and try to move your package to a similar structure. The
'all files in one directory' you have in https://github.com/thioulouse/RVrandtest
is not what R prefers.

Follow-up may be more suitable for the rcpp-devel list.  This list here is
general interest, your question is a bit more specific to ins and outs of
just one package.

Best, Dirk

-- 
dirk.eddelbuettel.com | @eddelbuettel | edd using debian.org



More information about the R-package-devel mailing list