问题
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?
回答1:
When you have code in two sources files
mvtnorm.cpp
calling your backend functionpmvnorm_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/
.
回答2:
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.)
来源:https://stackoverflow.com/questions/45911179/combine-r-c-and-fortran