I am writing an Rcpp package with classes containing base Rcpp objects that are non-intrusively exported to C types (see Extending Rcpp by Eddelbuettel and Francois, and this helpful vignette by coatless).
What this means is that if I have a class foo::bar
and a constructor for foo::bar
given a SEXP
, I can call a function like this:
//[[Rcpp::export]]
void func(foo::bar object){
// do something
}
My problem is that sourceCpp("foobar.cpp")
works exactly as expected, but R CMD build
complains about the RcppExports.cpp
file missing declarations for this new class.
Here is a minimum reproducible example, containing a foo::bar
class holding a single Rcpp::NumericVector
. It compiles with sourceCpp()
but the package will not build because foobar
is not found in RcppExports.cpp
:
foobar.cpp:
#include <RcppCommon.h>
// forward declare class
namespace foo {
class bar;
}
// forward declare Rcpp::as<> Exporter
template <>
class Rcpp::traits::Exporter<foo::bar>;
#include <Rcpp.h>
// now fully declare class, since Rcpp objects
// are now loaded from Rcpp.h
namespace foo {
class bar {
public:
Rcpp::NumericVector x;
bar(Rcpp::NumericVector x) : x(x) {};
};
}
// now fully declare Rcpp exporter, since we can
// deal with Rcpp objects from Rcpp.h
namespace Rcpp {
namespace traits {
template <>
class Exporter<foo::bar> {
Rcpp::NumericVector x_;
public:
Exporter(SEXP x) : x_(x) {}
foo::bar get() {
return foo::bar(x_);
}
};
}
}
//[[Rcpp::export]]
Rcpp::NumericVector test(foo::bar& A) {
return A.x;
}
The specific errors I am getting when running R CMD check
are all in the src/RcppExports.cpp
file:
- 'foo' has not been declared
- 'A' was not declared in this scope
- 'foo' was not declared in this scope
- 'template argument 1 is invalid
- 'qualified-id in declaration before 'A'
What needs to happen to get the package to build just like sourceCpp
?
Thanks for any solutions!
CodePudding user response:
RcppExports.cpp file missing declarations for this new class.
See the Attributes vignette. The custom behavior is to have a header named as the package (i.e. foo.h
for package foo
) and/or foo-types.h
) which will be added to the generated RcppExports.cpp
.
That is documented but hidden rather too effectively :-/ It's here too so we could close this as a dupe but I don't have time to search that now.