[Rcpp-devel] pointer to c++ object with modules
That fixed it! Thanks, Chris On Mon, Feb 6, 2012 at 11:09 AM, Romain Francois
<romain at r-enthusiasts.com>wrote:
Le 06/02/12 19:40, Chris DuBois a ?crit : Hi all,
I have a class that stores data and various statistics about my data. I want to be able to work with it from R and from C++ functions, but I do not want to have the entire data structure created as an R object. I thought one might be able to return a pointer from the object to R, and pass that pointer from R to a C++ function that needs to interact with the object. This seems to work until garbage collection occurs, at which point I get a segfault. I have included an example below illustrating my current approach. I altered the World example to return a pointer to the current object. I have a C++ function that makes changes to the object. I saw this post http://lists.r-forge.r-**project.org/pipermail/rcpp-** devel/2011-December/003214.**html<http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-December/003214.html> but I wanted to use modules and I haven't been able to adapt that solution to my situation. Any help/advice is much appreciated, Chris library(inline) library(Rcpp) fx <- cxxfunction(,"",includes= ' #include <Rcpp.h> class World { public: World() : msg("hello") {} void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } SEXP ptr() { return wrap(XPtr<World>(this, true)); } private: std::string msg; }; int fn(SEXP ptr_) { World *s = XPtr<World>(ptr_); s->set("c++ function has been here"); return 1; } RCPP_MODULE(example){ using namespace Rcpp ; function("fn", &fn); class_<World>( "World") .constructor() .method( "greet", &World::greet , "get the message") .method( "set", &World::set , "set the message") .method( "ptr", &World::ptr , "get a pointer"); } ', plugin="Rcpp") example <- Module("example",getDynLib(fx)**) s <- new(example$World) # Interact with World object from R s$greet() s$set("hello from R") s$greet() # Grab pointer to this World object s$ptr() # Call a c++ function that uses World object example$fn(s$ptr()) s$greet() # c++ function has altered s, as desired # Causes segfault gc()
That's subtle. When you call your ptr function, you create a new R
external pointer to encapsulate the same underlying C++ pointer. When the R
external pointer object you created goes out of scope, it becomes a
candidat for gabage collection. When GC occurs, the undelying pointer is
delete'd.
You could prevent the finalizer by using :
SEXP ptr() {
return XPtr<World>(this, false);
}
Also, you don't need wrap because XPtr has a SEXP operator inherited from
RObject.
Romain
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
R Graph Gallery: http://addictedtor.free.fr/**graphiques<http://addictedtor.free.fr/graphiques>
blog: http://romainfrancois.blog.**free.fr<http://romainfrancois.blog.free.fr>
|- http://bit.ly/xbKv0R : Crawling facebook with R
|- http://bit.ly/v3WB8S : ... And now for solution 17, still using Rcpp
`- http://bit.ly/uaQDGr : int64: 64 bit integer vectors for R
-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20120206/dd9b3634/attachment-0001.html>