Rcpp: Call C function from a package within Rcpp - r

I would like to write a C++ function with Rcpp that uses a C function found in the package hypred, which is on CRAN here.
I read using C function from other package in Rcpp, but don't understand if this applies for me and if it would apply, what to do.
The desired function is in the the source file /src/hypredRoutines.c and is called meiosisFUNAllChr.
What I so far did based on this SO question here is:
I separated the function meiosisFUNAllChr from the rest of the code and placed it in a new file called meiosisFUNAllChr.c.
I created a header file called meiosisFUNAllChr.h containing:
#ifndef MEIOSISFUNALLCHR_H
#define MEIOSISFUNALLCHR_H
void meiosisFUNallChr (...);
#endif
Compiled it with
gcc -c -o meiosisFUNAllChr.o meiosisFUNAllChr.c
Created a dummy c++ function
#include <Rcpp.h>
using namespace Rcpp;
extern "C" {
#include "meiosisFUNallChr.h"
}
// [[Rcpp::export]]
int timesTwo(int x) {
return x * 2;
}
At this point, compiling with sourceCpp does not work. Can you show me how to get it working?
Many Thanks!
EDIT
Compiling with sourceCpp gives me:
meiosisFUNallChr.h: file or directory not found

hypred registers its two functions, at the R level you can get hold of the one you want like this:
xp <- getDLLRegisteredRoutines( getLoadedDLLs()[["hypred"]] )[[".C"]][["meiosisFUNallChr"]]$address
I believe you can then access the function pointer in C++ like this:
DL_FUNC meiosisFUNallChr = reinterpret_cast<DL_FUNC>( R_ExternalPtrAddr(xp) ) ;
But you'd be better off negotiating with the package authors that they implement this scheme if you can make a case that you really need to be calling the C function directly.

Briefly:
You want to use another source file (presumably available under a suitable license).
You want to call it from a new file of yours.
So you already have two files.
By now the alarm bells should go off that you really, really, want to create a package.
Which the Rcpp documentation details in many places. And there are 340+ packages on CRAN using Rcpp, many doing this very issue of calling a C file too. Pick one or two, study their structure; also pick one or two created by the fully documented Rcpp tools such as Rcpp.package.skeleton() and things should become a lot clearer.
Edit: Obviously, this approach only needs to be taken if the other package does not export its function. If you can get its author to export, use that as mention in Romain's answer. Pairs of packages that export/use are zoo/xts, xts/RcppXts, expm/RcppKalman (not on CRAN), RApiSerialize/RcppRedis, ...

Related

Why do we both "include" and "depends" on RcppArmadillo?

To use RcppArmadillo, we're often instructed to have the following lines at the top:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
Why do we need both? Isn't the #include directive sufficient for us to have access to all functions defined inside the scope of RcppArmadillo?
There are two different things at play:
The compiler needs the header RcppArmadillo.h in order to know about types from (Rcpp)Armadillo, Rcpp (as this one pulls in Rcpp.h as well) and therefore R. I presume you know you need this. But ...
How would R know to add the -I... flag required for this? It wouldn't!
At a package level the LinkingTo: helps for the header case. But in deeper sense sometimes we need headers and linking (ie RcppGSL) and in that case, the hook we have here via Rcpp::depends into Rcpp Attributes ensures we can do this.
So the // [[Rcpp::depends(RcppArmadillo)]] helps for sourceCpp() use. It is not needed in a package. "Plugins" like this are discussed a little in the Rcpp Attributes vignette.

Combine R, C++ and Fortran

I am trying to reimplement an R function using C++ and RCpp to speed up the computation. And in the C++ implementation, I need to use a Fortran function mvtdst found in link.
#include <Rcpp.h>
#include "mvtnorm.h"
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector pmvnorm_rcpp(NumericVector upper, NumericMatrix corr)
{
double error;
double mvnP = pmvnorm_P(2, upper, corr, &error) ;
return mvnP ;
}
/*** R
pmvnorm_rcpp(c(1.5,1.5),c(0.0))
*/
Here, pmvnorm_P is defined in the mvtnorm.cpp file.
All the files found in link are kept in the working directory along with the RcppWrapper.cpp file.
When I compile my RcppWrapper.cpp file using sourceCpp() function in RCpp package, it gives the following error.
mvtnorm.o:mvtnorm.cpp:(.text+0x7c): undefined reference to `mvtdst_'
collect2.exe: error: ld returned 1 exit status
Error in Rcpp::sourceCpp("RcppWrapper.cpp") :
Error occurred building shared library.
Does anyone know how to resolve this error?
When you have code in two sources files
mvtnorm.cpp calling your backend function pmvnorm_P()
another file providing it
then you also must provide link instructions. Simply put, sourceCpp() is only intentended and working for one-file solutions (unless you give link instructions).
Simplest fix: just create a package assembling all your files in src/.
Fortran and C++ mangle the names of functions differently. It looks like mvtdst is the name of your Fotran function. (Right?) You need to "mangle" that by hand when called from C++. So instead of calling mvtdst, call mvtdst_ with the trailing underscore.
Unfortunately, compilers are not consistent in the mangling, so this will not be portable. (To make it portable, you'll need some sort of preprocessing that matched the mangling to the compiler.)

Rcpp integrated with R package: Documentation of CPP code objects

I have been developing a package with Rcpp for C++ integration. I used RcppExport to make the functions return SEXP objects.
The issue is travis-ci seems to give warnings telling that there are undocumented code objects. (These are cpp functions). However I do not want users to directly access those functions as well.
How can I resolve this issue? How can I document these functions as well?
You seem to have an elementary misunderstanding here.
If your NAMESPACE contains a wildcard 'export all' a la exportPattern("^[[:alpha:]]+") then each global symbol is exported and per R standards that are clearly documented needs a help entry.
One easy fix is NOT to export everything and just write documentation for what you want exported. We sometimes do that and call the Rcpp function something like foo_impl and then have R functions foo (with documentation) call foo_impl. In that case you would just export foo and all is good.
In short, you are confused about R packages and not so much Rcpp. I would recommend downloading the sources of a few (small) Rcpp packages to get a feel for what they do.

Equivalent of c++ include in R

I have 3 scripts logs.R, func.R, main.R and I want to log from main and also from func scripts. I know that I can use source, for having the functions in both scripts, but sourcing logs in func and in main, is the same of sourcing it 2 times (I source func in main). Is there any equivalent of #pragma once or #ifndef #define #endif from C++ ?
You can mimic that with a custom variable and a condition.
logs.R
...
log.sourced <- TRUE
func.R
if(!exists("log.sourced")) source("logs.R")
...
main.R
if(!exists("log.sourced")) source("logs.R")
...
Or just test exists("func") where func is defined in logs.R
use the source("otherfile.R") to include the content of other files. (equivalent of include).
As R is directly interpreted and no preprocessed, there is not equivalent of #pragma once or include guards directive.
One way to replace the include guards would be to write in directly in R.
Since there’s no proper solution in base R and other solutions require on hacky mechanisms like include guards, I wrote my own package: ‘box’.
With modules you can for instance write the following code:
box::use(./logs)
And now you can use logs like a package/namespace you’re used to in other languages: logs$log('Some string I’d like to log.'). Or, alternatively, you could do
box::use(./logs[...])
This mimics R’s normal attaching mechanism, and is similar to using namespace foo in C++. See the ‘box’ vignette for a more in-depth introduction.

Error when building R package using roxygen2

I have 2 files, Rfile.R and Cppfile.cpp.
Contents in Cppfile.cpp:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int CPPF(int k){return ++k;}
Contents in Rfile.R:
RF<-function(k){return(CPPF(k))}
I want to build an R package based on the 2 files. I use the lastest versions of Rstudio and Roxygen2.
I tried 3 ways to build the package with or without Roxygen2, and had different results:
New Project->New Directory->R package->Type:Package w/Rcpp, add both Rfile.R and Cppfile.cpp as source files. Build & reload, everything works out fine. The functions work as they do.
New Project->New Directory->R package->Type:Package w/Rcpp, add both Rfile.R and Cppfile.cpp as source files. Select "Generate documentations with Roxygen", check all its options. Build & Reload, the functions don't work. Inputting "RF" gives the contents of RF, inputting "CPPF" pops "Object not found".
New Project->New Directory->R package->Type:Package w/Rcpp, add only Cppfile.cpp as source files. Select "Generate documentations with Roxygen", check all its options. Build & Reload, the function works.
Then copy Rfile.R directly into the project folder->R folder. Build & Reload, everything fine, functions work well.
Am I using the Roxygen wrong or Roxygen has bugs? I need it to document. I can stick to the 3rd way which cost me much energy to find, but wired.
Thanks!
One Way To Solve The Issue:
When selecting "Generate documentations with Roxygen", Don't check "NAMESPACE file" option.
You're mixing up two things (which are easy to mix up, unfortunately):
First, the // [[Rcpp::export]] attribute is used for auto-generating wrapper functions in two files, RcppExports.cpp and RcppExports.R. A wrapper R function, CPPF, will be auto-generated by Rcpp::compileAttributes() here, and placed into R/RcppExports.R.
Second, roxygen comments can be used to manage the NAMESPACE, e.g. with the #export tag. Note that this is different from // [[Rcpp::export]]!
The auto-generated function is not automatically exported. The Rcpp.package.skeleton() will generate a NAMESPACE file that automatically exports all functions of a given name; ie, the exportPattern("^[[:alpha:]]+") entry. This is good enough for small packages; but as your package gets more complicated you will want more fine-grained control over your namespace. Or you can just adopt a convention where all internal, non-exported functions begin with a .. Either way, this mechanism is what allows the auto-generated function to be exported to your package namespace.
If you want to use roxygen to manage the NAMESPACE, you need to add roxygen comments to your C++ functions if you want them to be exported in the namespace. So you could modify your function as the following:
#include <Rcpp.h>
using namespace Rcpp;
//' #export
// [[Rcpp::export]]
int CPPF(int k){return ++k;}
Note that you might have to run roxygen2::upgradeRoxygen() to ensure that roxygen2 takes over the NAMESPACE, for new versions of roxygen2.
So if 2. does not work, file it as a (reproducible) bug report with the roxygen2 team.
I see no Rcpp issue; it is possible that something went wrong with the Imports: / NAMESPACE declaration. I see no Rcpp issue here (as 1. works fine).
FWIW I also use roxygen2 on some packages, and I too build them from time to time in RStudio.

Resources