cdeterman
cdeterman

Reputation: 19970

Wrapping a fortran function in Rcpp

This initially appeared to me to be a simple task but I cannot get the following to work. I am trying to wrap a fortran subroutine into a Rcpp call in order to have the function available in R to use. The goal is to incorporate the function into a package so the idea of just using dyn.load() on the specific *.so file isn't feasible (unless someone can show me how?). From reading similar posts I suspect specifying flags in the makevars file may solve the problem but the information provided is very terse here and some clarification would be sincerely appreciated.

I have done the following as close to documentation as I could follow.

  1. Create the package structure with Rcpp.package.skeleton
  2. Place my fortran file (hello.f) in the src directory
  3. Created a basic cpp file for the Rcpp wrapper (hello.cpp)
  4. Create a R file to create a 'clean' function call (i.e. avoid the .Call for the user and allow for running other internal calculates prior to the .Call)

However, when I try and build my package (with RStudio), I get the following error output:

==> R CMD INSTALL --no-multiarch --with-keep.source fortran

g++ -shared -o fortran.so RcppExports.o hello.o hello.o rcpp_hello_world.o -lgfortran -lm -lquadmath -L/usr/lib/R/lib -lR
* installing to library ‘/home/.../R/x86_64-pc-linux-gnu-library/3.0’
* installing *source* package ‘fortran’ ...
** libs
hello.o: In function `hello_wrapper':
/home/.../r_code/fortran/src/hello.cpp:16: multiple definition of `hello_wrapper'
hello.o:/home/.../r_code/fortran/src/hello.cpp:16: first defined here
collect2: error: ld returned 1 exit status
make: *** [fortran.so] Error 1
ERROR: compilation failed for package ‘fortran’
* removing ‘/home/.../R/x86_64-pc-linux-gnu-library/3.0/fortran’

Exited with status 1.

My files are as follows:

hello.f

subroutine hello()
    print *, "hello world"
end subroutine hello

hello.h

extern "C"
{
  void hello();
}

hello.cpp

#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>

#include "hello.h"

#ifdef __cplusplus
extern "C"
{
  SEXP hello_wrapper();
}
#endif

SEXP
hello_wrapper ()
{
  hello();
}

wrapper.R

hello_r <- function(){
  .Call("hello_wrapper");
}

Upvotes: 4

Views: 1161

Answers (2)

Kevin Ushey
Kevin Ushey

Reputation: 21315

I believe the issue is as simple as R being unhappy when you include multiple files of the name name with different extensions. Try renaming hello.f to hello_fortran.f and going from there.

Upvotes: 2

Dirk is no longer here
Dirk is no longer here

Reputation: 368489

I think this may work if you remove the

#ifdef __cplusplus
extern "C"
{
  SEXP hello_wrapper();
}
#endif

part. Also look at the Rcpp Attributes vignette -- you don't need to write wrapper.R by hand.

Upvotes: 1

Related Questions