Monday, March 16, 2015

Accessing C++ objects from R using Rcpp

Rcpp (Seemless R and C++ integration) package for R provides an easy way of combining C++ and R code. Since R is an interpreter, a bulk of code would probably run at least 2 times slower than its counterpart written in C++. Speed is the most concerning issue many times, however, the main purpose of using C++ would be using an old native library with R.

In this post blog, we give an example of accessing a C++ class from within R using Rcpp. This C++ class is defined with name MyClass and has two private double typed variables. This class also has getter and setter methods for its private fields.

MyClass is defined as the code shown below:


#include <Rcpp.h>

using namespace Rcpp;
using namespace std;


class MyClass {
  private:
    double a,b;
  
  public:
    MyClass(double a, double b);
    ~MyClass();
    void setA(double a);
    void setB(double b);
    double getA();
    double getB();
};



MyClass has its private double typed variables a and b, a constructor, a destructor, getter and setter methods for a and b, respectively. The implementation of MyClass is given below:




MyClass::MyClass(double a, double b){
    this->a = a;
    this->b = b;
}

MyClass::~MyClass(){
    cout << "Destructor called" << std::endl;
}

void MyClass::setA (double a){
    this->a = a;
}

void MyClass::setB (double b){
    this->b = b;
}

double MyClass::getA(){
    return(this->a);
}

double MyClass::getB(){
    return(this->b);
}


MyClass is defined nearly minimal. Since it is a C++ class it is not directly accessable from R. In this example, we write some wrapper methods to create instances of MyClass and return their addresses in memory to perform later function calls. In other terms, in R side, we register address of C++ objects to access them. 


// [[Rcpp::export]]
long class_create(double a, double b){
    MyClass *m =  new MyClass(a,b);
    class_print((long) m);
    return((long)m);
}

The method class_create is a C++ method and it has a special comment which will be used by Rcpp before compiling. After compiling process, class_create wrapper R function will be created to call its C++ counterpart. This function create an instance of class_create with given double typed values and returns the address of created object in type long integer.  Here is the other wrapper functions:


// [[Rcpp::export]]
void class_print(long addr){
    MyClass *m = (MyClass*)addr;
    cout << "a = " << m->getA() << " b = " << m->getB() << "\n";   
}


// [[Rcpp::export]]
void class_destroy(long addr){
    MyClass *m = (MyClass*) addr;
    delete m;
}

// [[Rcpp::export]]
void class_set_a(long addr, double a){
    MyClass *m = (MyClass*) addr;
    m->setA(a);
}

// [[Rcpp::export]]
void class_set_b(long addr, double b){
    MyClass *m = (MyClass*) addr;
    m->setB(b);
}

// [[Rcpp::export]]
double class_get_a(long addr){
    MyClass *m = (MyClass*) addr;
    return(m->getA());
}

// [[Rcpp::export]]
double class_get_b(long addr){
    MyClass *m = (MyClass*) addr;
    return(m->getB());
}

Suppose the whole code is written in a file classcall.cpp.  In R side, this code can be compiled and tested as shown below:

> require("Rcpp")
Loading required package: Rcpp
> Rcpp::sourceCpp('rprojects/classcall.cpp')
> myobj <- class_create(3.14, 7.8)
a = 3.14 b = 7.8
> myobj
[1] 104078752
> class_set_a(myobj,100)
> class_set_b(myobj,500)
> class_print(myobj)
a = 100 b = 500

> class_get_a(myobj)
[1] 100
> class_get_b(myobj)
[1] 500
> class_destroy(myobj)
Destructor called


Have a nice read!


No comments:

Post a Comment

Thanks