[Rcpp-devel] Can an Rcpp package include Fortran code?
John Buonagurio
jbuonagurio at exponent.com
Thu Oct 6 20:15:47 CEST 2016
On 6 October 2016 at 12:19, Avraham Adler wrote:
| Has anyone successfully created a package that uses Rcpp for C++ code
| and which also has Fortran code? I'm experimenting with comparing
| Fortran and C++ and if I could use Rcpp to handle the C++ portion, it
| would reduce the steepness of the learning curve.
|
| However, I haven't had success. The following C++ and Fortran snippets
| compile properly separately—the C++ as part of Rcpp and the Fortran
| using R CMD SHLIB and dynload—and the R snippets call them properly,
| but when I put both the .cpp and .f95 files in /src, I get the huge
| error posted below the files.
|
| Am I missing something simple or will having C++ and Fortran code in
| the same package prevent the use of Rcpp and require the old methods
| of calling compiled code?
Avi,
Take a look at my package 'htdp' for a complete example:
https://github.com/jbuonagurio/RHTDP
Specifically:
src/Makevars
src/RcppHTDP.cpp
src/htdp/htdp.h
src/htdp/README
A few notes:
1. I have a single Fortran file with F95 INCLUDE statements to simplify
the build, at the cost of incremental linking. You don't have to do
this, see the 'matrix' package on CRAN for a more complex build example.
2. Set 'PKG_LIBS = $(FLIBS)' in Makevars to link the appropriate
libraries (-lgfortran -lquadmath -lm).
3. Do not use Fortran I/O if you want your package on CRAN (e.g. WRITE,
STOP). Use the R-only versions of error and warning (REXIT, RWARN).
These are defined in src/main/xxxpr.f in the R sources.
4. This package will probably only work with gfortran, which exports all
symbols with a trailing underscore by default. Make sure your function
prototypes have the underscore in the header file, with extern "c".
5. A better and more interoperable way to call Fortran from C/C++ is to
use ISO_C_BINDING, which lets you pass by value, set number of bytes for
storage, etc. I originally set up this package to use ISO_C_BINDING,
however I realized later that earlier versions of gfortran (before GCC
4.9.3) require explicit interfaces which I didn't want to bother with.
You probably should. See this older commit for the ISO_C_BINDING version:
<https://github.com/jbuonagurio/RHTDP/commit/5912279aa139b15baa435db2d6e6f78807a707a3>
6. Don't use .Fortran(). Call the Fortran code from C++, and let Rcpp
attributes create the .Call() statements for you.
Dirk/Kevin, please feel free to add/revise!
Best,
John Buonagurio
More information about the Rcpp-devel
mailing list