Reputation: 472
I tried to call c++ function from another .cpp file. I used .h header. See below what I did.
I have a f.h file:
#ifndef PACKAGENAME_ADD_H
#define PACKAGENAME_ADD_H
#include <Rcpp.h>
Rcpp::NumericVector f(Rcpp::NumericVector x) ;
#endif
f.cpp file:
#include <Rcpp.h>
using namespace Rcpp;
NumericVector f(NumericVector x) {
return x * 2;
}
g.cpp file:
#include <Rcpp.h>
#include <f.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector g(NumericVector x) {
return f(x);
}
The three files are in the same folder I got this error when I run g.cpp:
Rcpp::sourceCpp('~/g.cpp')
Error in dyn.load("/tmp/Rtmpdu4AWp/sourceCpp-x86_64-pc-linux-gnu-0.12.17/sourcecpp_260f5e1a9ebc/sourceCpp_9.so") : unable to load shared object '/tmp/Rtmpdu4AWp/sourceCpp-x86_64-pc-linux-gnu-0.12.17/sourcecpp_260f5e1a9ebc/sourceCpp_9.so': /tmp/Rtmpdu4AWp/sourceCpp-x86_64-pc-linux-gnu-0.12.17/sourcecpp_260f5e1a9ebc/sourceCpp_9.so: undefined symbol: _Z1fN4Rcpp6VectorILi14ENS_15PreserveStorageEEE
Can someone help me? I work on ubuntu 18.04 and I have R 3.4.4 version.
Upvotes: 2
Views: 625
Reputation: 16910
The way I am most familiar with dealing with this issue in the context of Rcpp
is by creating a package. In the case you present in the original post, as pointed out by Ralf Stubner it isn't really necessary; after changing the brackets(<>
) around f.h
in g.cpp
to quotes (""
), your code compiled fine for me with sourceCpp()
:
Rcpp::sourceCpp("g.cpp")
g(1:10)
# [1] 2 4 6 8 10 12 14 16 18 20
(for details see section 1.10 of the Rcpp Attributes vignette).
However, if you are eventually needing multiple .cpp
files to compile (i.e., not just one that relies on an implementation in another), the way to go is creating a package. This might sound involved or intimidating, but with the tools provided by Rcpp
, it's really quite simple. Here are the steps I took to turn your code into a package:
Rcpp::Rcpp.package.skeleton("SOanswer", example_code = FALSE)
Read-and-delte-me
.src/
folder (with only one minor edit -- changing the brackets(<>
) around f.h
in g.cpp
to quotes (""
)).Rcpp::compileAttributes("SOanswer/")
and devtools::install("SOanswer/")
Then it should compile nicely and you can run g()
from R:
SOanswer::g(1:10)
# [1] 2 4 6 8 10 12 14 16 18 20
I will say that I would add there a step 0: Read the vignettes at https://cran.r-project.org/package=Rcpp, in particular the Rcpp Introduction and Rcpp Package vignettes. You can also check out this lovely example of a package with headers in src/
provided by coatless in the comments.
Upvotes: 3