Maaehj
Maaehj

Reputation: 161

How to store CPP classe in R object?

I want to know if there is a way to store a CPP class in a R object.

I understand that we can call CPP function in R and we can also call method of a CPP class.

But I want to manipulate the CPP class in a R object, I don't know if this is possible.

Example :

I call this code in a R Script :

dyn.load(paste("X", .Platform$dynlib.ext, sep = ""))
.C("X_main")

The function X_main :

extern "C" {
void X_main () {
  X x;
}
}

in X.cpp :

X::X()  { cout<<"constructor X\n"<<endl;}

Can I store an object of the class "X" in a R object ? And use method of class "X" on the object stored (after in the script) ?

Or, Can I store in the memory an object of the class X ? I want to use this object several times.

Upvotes: 1

Views: 505

Answers (2)

Danielle
Danielle

Reputation: 141

You can load a C++ class (and probably struct) within R, which saves variables within class scope. R treats C++ classed like an S4 class.

Under the hood, a pointer to a C++ object instance is passed around, so you can create an object instance in C++ and then pass it to R sharing data.

To learn how to do this, it's about 7 pages, but well worth the read, so get out a cup of coffee and checkout: Exposing C++ functions and classes with Rcpp modules by Dirk Eddelbuettel and Romain François.

An example from the pdf:

class Bar { 
public:

    Bar(double x_) : x(x_), nread(0), nwrite(0) {}

    double get_x() {
        nread++;
        return x; 
    }

    void set_x(double x_) {
        nwrite++;
        x = x_; 
    }

    IntegerVector stats() const { 
        return IntegerVector::create(_["read"] = nread,
                                     _["write"] = nwrite);
    }

private: 
    double x;
    int nread, nwrite;
};

RCPP_MODULE(mod_bar) {
    class_<Bar>( "Bar" )

    .constructor<double>()

    .property( "x", &Bar::get_x, &Bar::set_x )
    .method( "stats", &Bar::stats )
    ;
}

And in R:

Bar <- mod_bar$Bar 
b <- new(Bar, 10) 
b$x + b$x 
b$stats()
b$x <- 10 
b$stats()

Upvotes: 1

Dirk is no longer here
Dirk is no longer here

Reputation: 368579

By writing converters, you can assign the components of X which map to types R also knows: integer, numeric, character, ... all as scalar or vector, and of course composites of these.

But you do not get it for free. With Rcpp and friends, we have all the wrapper -- as well as a bunch of build tools -- to make this easy:

R> library(Rcpp)
R> cppFunction("arma::mat doubleIt(arma::mat X) { return 2*X; }", 
+              depends="RcppArmadillo")
R> doubleIt(matrix(1:9,3))
     [,1] [,2] [,3]
[1,]    2    8   14
[2,]    4   10   16
[3,]    6   12   18
R> 

There are over 900 other Rcpp questions here, almost 100 worked examples at the Rcpp Gallery site. Have a look around!

Upvotes: 1

Related Questions