Skip to content
Prev 46082 / 63424 Next

Calling an array in a struct in C to R

Hello,

I would use external pointers for something like this.

If c++ is an option, you can take advantage of Rcpp classes to deal with 
external pointers. Put the following in a .cpp and sourceCpp() it.

#include <Rcpp.h>
using namespace Rcpp ;

class Array {
public:
     Array( ) : size(10), used(0){
         array = new float[10] ;
     }

     ~Array(){
         delete[] array ;
     }

     size_t get_used(){ return used ; }
     // other methods doing stuff with the data

private:
     float *array;
     size_t used;
     size_t size;
} ;
typedef XPtr<Array> ArrayPointer ;

// [[Rcpp::export]]
ArrayPointer create_ptr( ){
     return ArrayPointer( new Array ) ;
}

// [[Rcpp::export]]
size_t Array_get_used(ArrayPointer obj){
     // here we use ArrayPointer just like an Array*
     return obj->get_used() ;
}

Now, this is very raw and at the R level you get opaque external pointers:

 > a <- create_ptr()

 > str(a)
<externalptr>

 > Array_get_used(a)
[1] 0



You can go further than this and use Rcpp modules so that you don't need 
to worry about external pointers, which you can consider as 
implementation details. For example:

#include <Rcpp.h>
using namespace Rcpp ;

class Array {
public:
     Array( ) : size(10), used(0){
         array = new float[10] ;
     }

     ~Array(){
         delete[] array ;
     }

     size_t get_used(){ return used ; }
     // other methods doing stuff with the data

private:
     float *array;
     size_t used;
     size_t size;
} ;

// the module code, this is where you declare what of
// your class you expose to the R level
RCPP_MODULE(ArrayModule){
     class_<Array>("Array")
         .constructor()
         .method( "get_used", &Array::get_used)
     ;
}

With this, the R code looks like this:

# we should get rid of the need to call populate.
# for now let us just assume it is a way to copy
# the content of the module
# into the global environment
 > populate(ArrayModule, globalenv())

 > b <- new(Array)

 > str(b)
Reference class 'Rcpp_Array' [package ".GlobalEnv"] with 0 fields
  list()
  and 15 methods, of which 3 are possibly relevant:
    finalize, get_used, initialize

 > b$get_used()
[1] 0

Romain

Le 19/06/13 16:14, Tee-Jay-Ardie a ?crit :