Combine R, C++ and Fortran

廉价感情. 提交于 2019-12-14 03:25:22

问题


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 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/.




回答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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!