问题
I have existing C code that consists of three files: a header file ( a ".h" file), a library file (a ".o" file), and a source file. They currently run under UNIX and as compiled "mex files" in Matlab. I would like to port them to R using Rcpp. They are all long and complex, so I made a minimal example to help me understand how to port them to R.
The simplified header file (my_header.h) is:
typedef unsigned int ui4;
ui4 add_one( ui4 );
The simplified "library" file (my_lib.cpp) is:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "my_header.h"
ui4 add_one(ui4 x) {
return(x+1);
}
The simplified function program (my_program.cpp) is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <Rcpp.h>
#include <cmath>
#include "my_header.h"
using namespace Rcpp;
// [[Rcpp::export]]
ui4 my_program_r () {
//int main (int argc, const char * argv[]) {
//
// As a MATLAB mex file, this function calls "main(..."
//
ui4 value = add_one( (ui4)1 );
printf( "%d", value );
return value;
}
From the terminal (I'm on a Mac), I can compile these without an error:
$ g++ my_lib.cpp -c -o my_lib.o
$ g++ my_program.cpp -o my_program my_lib.o
When I try to compile them in RStudio, I get:
> library(Rcpp)
> sourceCpp( "my_program.cpp" )
Warning message:
In sourceCpp("my_program.cpp") :
No Rcpp::export attributes or RCPP_MODULE declarations found in source
>
Why isn't this compiling under Rcpp? How do I specify the linked file (the ".o" library file) in the "sourceCpp" command? Do I need to specify the header file?
回答1:
The sourceCpp
command is meant for single files only. If you have multiple files, you have to use a package:
- Call
Rcpp::Rcpp.package.skeleton(...)
to create a skeleton package. - Copy
*.h
,*.c
and*.cpp
to thesrc
folder. - Call
Rcpp::compileAtrributes()
. - Use
R CMD build ...
,R CMD check ...
andR CMD INSTALL ...
to build, check and compile the package. (Thecheck
will complain about undocumented functions ...)
For more details see Rcpp-package vignette and for example this question. BTW, since R does not have an unsigned int
type, I am not sure if your return value will work. You might have to switch to an int
or double
. I also get a different error message than you:
Error in dyn.load("/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so") : unable to load shared object '/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so': /tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so: undefined symbol: _Z7add_onej
Are you sure the above code is exactly what you used?
来源:https://stackoverflow.com/questions/50770830/simplified-example-using-rcpp-to-link-an-object-file-to-a-function