Hi all, I wrote a wrapper of hiredis, which is a minimalistic C client for the Redis database. Its name is `Rhiredis` and is much faster than rredis, an existed redis client of R. Please see http://rpubs.com/wush978/rhiredis for details.
Thanks for the Rcpp, it is much easier to wrap a C library into R and extend the features of R. However, I still want to know if there is a better approach. I tried three approaches. Here is my opinions. # Preliminary Given a 3rd party C library, it usually provides a C structure and functions of memory management. For example: ```c struct A { int flag; // ... }; A* initA(); void freeA(A* a); ``` The structure `A` need to be stored into a R object and pass to another function. Also, the user might need to access `A.flag`. For simplicity, there is only one field in this example. However, there might be a number of fields in practice. # XPtr Thanks for the user guide of Rcpp modules , this is the first approach I tried. We could expose `A` into R as follow: ```cpp Rcpp::XPtr<A, freeA> a(initA()); ``` However, we should write helper function to accessing `A.flag` for every fields. # RCPP_MODULE The guids of Rcpp modules also provides another approach: ```cpp RCPP_EXPOSED_CLASS(A) RCPP_MODULE(A) { class_<A>("A") .field("flag", &A::flag) ; } //'@export //[[Rcpp::export]] SEXP init() { BEGIN_RCPP return wrap(*initA()); END_RCPP } ``` This will produce a S4 class named `A` in R which stores C structure `A`. However, it also produces memory leak because no `freeA` is called. Adding `.finalizer(freeA)` in `RCPP_MODULE` will cause an error of freeing memory twice. # Embed `A` into C++ class and expose the class with RCPP_MODULE This approach is implemented in `Rhiredis`. Finally, I still need to write helper function to expose the field of `A`. But the user could access these flag in R with operator `$`. Note that I still need a function to extract the pointer of `A` from exposed S4 object: ```cpp template<class T> T* extract_ptr(SEXP s) { Rcpp::S4 s4(s); Rcpp::Environment env(s4); Rcpp::XPtr<T> xptr(env.get(".pointer")); return static_cast<T*>(R_ExternalPtrAddr(xptr)); } ``` Please give me some suggestion if you know a better or a different approach. Thanks. Wush
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel