Home > other >  Non-intrusive extension of Rcpp with Rcpp::traits::Exporter
Non-intrusive extension of Rcpp with Rcpp::traits::Exporter

Time:11-04

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.

  • Related