Hi there, Although I'm a quite experienced R user and know my ways in C, I stumbled upon a problem I don't know how to solve. Therefore, I hope someone can provide me with the information or pointers I need in order to understand the way in which the communication between R and C occurs. I have the following C code which basicallly reflects what I want: typedef struct { float *array; size_t used; size_t size; } Array; void main2R() { Array a; examplefunction(&a); /*fills and dynamically grows a->array*/ } Now I would want to return a.array or a->array to R. According to the R manuals, the compiled C code should not return anything except through its arguments. The problem here is, I have a dynamically growing array, and I have no idea what to pass on to C from R in order to let that work. The word 'should' indicates that the compiled code may return something in special circumstances, but I have no idea how to get a.array in R. So my question is simply this: How on earth do I get the information in the float array 'a.array' in R? Is it even possible or should I rewrite my C code using Call in R? Another, not preferred, options is to pre-allocate the array/vector in R on a fixed (large-enough) size? Or do I miss something here? Regards. -- View this message in context: http://r.789695.n4.nabble.com/Calling-an-array-in-a-struct-in-C-to-R-tp4669884.html Sent from the R devel mailing list archive at Nabble.com.
> should I rewrite my C code using Call in R?Yes, rewrite it to use the .Call() interface. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-devel-bounces at r-project.org [mailto:r-devel-bounces at r-project.org] On Behalf > Of Tee-Jay-Ardie > Sent: Wednesday, June 19, 2013 7:15 AM > To: r-devel at r-project.org > Subject: [Rd] Calling an array in a struct in C to R > > Hi there, > > Although I'm a quite experienced R user and know my ways in C, I stumbled > upon a problem I don't know how to solve. Therefore, I hope someone can > provide me with the information or pointers I need in order to understand > the way in which the communication between R and C occurs. I have the > following C code which basicallly reflects what I want: > > typedef struct > { > float *array; > size_t used; > size_t size; > } Array; > > void main2R() > { > Array a; > examplefunction(&a); /*fills and dynamically grows a->array*/ > } > > Now I would want to return a.array or a->array to R. According to the R > manuals, the compiled C code should not return anything except through its > arguments. The problem here is, I have a dynamically growing array, and I > have no idea what to pass on to C from R in order to let that work. > The word 'should' indicates that the compiled code may return something in > special circumstances, but I have no idea how to get a.array in R. > > So my question is simply this: How on earth do I get the information in the > float array 'a.array' in R? Is it even possible or should I rewrite my C > code using Call in R? > > Another, not preferred, options is to pre-allocate the array/vector in R on > a fixed (large-enough) size? Or do I miss something here? > > Regards. > > > > -- > View this message in context: http://r.789695.n4.nabble.com/Calling-an-array-in-a- > struct-in-C-to-R-tp4669884.html > Sent from the R devel mailing list archive at Nabble.com. > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Another solution is the one used for a long time in the rpart code. The R code called "rpart1", which does the work, keeps a static pointer to the object, does NOT release it's memory, and returned the size of the object. Then the R code allocates appropriate vectors and called "rpart2", which filled in the result and released the dynamic memory. This was written before .Call was available. It works, but I agree with Bill Dunlap that you should use .Call. Terry T. On 06/20/2013 05:00 AM, r-devel-request@r-project.org wrote: Hi there, Although I'm a quite experienced R user and know my ways in C, I stumbled upon a problem I don't know how to solve. Therefore, I hope someone can provide me with the information or pointers I need in order to understand the way in which the communication between R and C occurs. I have the following C code which basicallly reflects what I want: typedef struct { float *array; size_t used; size_t size; } Array; void main2R() { Array a; examplefunction(&a); /*fills and dynamically grows a->array*/ } Now I would want to return a.array or a->array to R. According to the R manuals, the compiled C code should not return anything except through its arguments. The problem here is, I have a dynamically growing array, and I have no idea what to pass on to C from R in order to let that work. The word 'should' indicates that the compiled code may return something in special circumstances, but I have no idea how to get a.array in R. So my question is simply this: How on earth do I get the information in the float array 'a.array' in R? Is it even possible or should I rewrite my C code using Call in R? Another, not preferred, options is to pre-allocate the array/vector in R on a fixed (large-enough) size? Or do I miss something here? Regards. Tee-Jay-Ardie [[alternative HTML version deleted]]
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 :> Hi there, > > Although I'm a quite experienced R user and know my ways in C, I stumbled > upon a problem I don't know how to solve. Therefore, I hope someone can > provide me with the information or pointers I need in order to understand > the way in which the communication between R and C occurs. I have the > following C code which basicallly reflects what I want: > > typedef struct > { > float *array; > size_t used; > size_t size; > } Array; > > void main2R() > { > Array a; > examplefunction(&a); /*fills and dynamically grows a->array*/ > } > > Now I would want to return a.array or a->array to R. According to the R > manuals, the compiled C code should not return anything except through its > arguments. The problem here is, I have a dynamically growing array, and I > have no idea what to pass on to C from R in order to let that work. > The word 'should' indicates that the compiled code may return something in > special circumstances, but I have no idea how to get a.array in R. > > So my question is simply this: How on earth do I get the information in the > float array 'a.array' in R? Is it even possible or should I rewrite my C > code using Call in R? > > Another, not preferred, options is to pre-allocate the array/vector in R on > a fixed (large-enough) size? Or do I miss something here? > > Regards.-- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 R Graph Gallery: http://gallery.r-enthusiasts.com blog: http://blog.r-enthusiasts.com |- http://bit.ly/13SrjxO : highlight 0.4.2 `- http://bit.ly/10X94UM : Mobile version of the graph gallery