1
votes

I am trying to use Rcpp Modules to expose C++ classes to R. I tried to create a simple example to understand how this works. I have two classes Bar and Foo that are stored in their own cpp files, in the src folder of the package. The code for Bar.cpp is the following:

#include "Bar.h"
#include "Foo.h"
#include <Rcpp.h>
using namespace Rcpp;

Bar::Bar(){x = 0;};

int Bar::getX(){return x;}

void Bar::setX(int num){x = num;}

int Bar::sumXY(){
  Foo f = Foo();
  f.setY(5);
  return x + f.getY();
}

RCPP_MODULE(bar_mod){
  class_<Bar>("Bar")
  .constructor()
  .method("getX", &Bar::getX)
  .method("setX", &Bar::setX)
  .method("sumXY", &Bar::sumXY)
  ;
}

The code for its header file is the following.

class Bar{
public:
  Bar();
  int getX();
  void setX(int num);
  int sumXY();
private:
  int x;
};

The code for Foo.cpp is the following.

#include "Foo.h"
#include <Rcpp.h>
using namespace Rcpp;

Foo::Foo(){
  y = 0;
}

int Foo::getY(){return y;}

void Foo::setY(int num){y = num;}

RCPP_MODULE(foo_module){
  class_<Foo>("Foo")
  .constructor()
  .method("getY", &Foo::getY)
  .method("setY", &Foo::setY)
  ;
}

The code for its header file is the following.

class Foo{
public:
  Foo();
  int getY();
  void setY(int num);
private:
  int y;
};

The Bar.cpp file includes both header files (Bar.h and Foo.h). The setXY() method in Bar creates a Foo object and calls its methods (so it uses classes and methods outside of its own file).

I would like to create objects from both of these classes in R, and call their methods. I am trying to load these modules in R using the following code:

require(Rcpp)
loadModule("foo_mod", TRUE)
loadModule("bar_mod", TRUE)

foo_mod <- Module("foo_mod")
bar_mod <- Module("bar_mod")

foo <- new (Foo)
bar <- new (Bar)

However, I get the following error:

Error in .getClassesFromCache(Class) : object 'Foo' not found

What am I doing incorrectly?

1

1 Answers

0
votes

I think you may just be sloppy with your naming. Try a more consistent use of identifiers in the macro RCPP_MODULE and the loader, ie I would use

RCPP_MODULE(bar)   // not bar_mod
//...
RCPP_MODULE(foo)   // not foo_modules

and then load (in a package, this is important) via

loadModule("foo", TRUE)
loadModule("bar", TRUE)

after which you can do (once you loaded the package, again this is a must)

z <- new(foo)

See eg my RcppAnnoy package.