Darren, That's an awesome answer!
Thank you very much!!!! -- Noah Silverman UCLA Department of Statistics 8117 Math Sciences Building Los Angeles, CA 90095 On Sep 7, 2011, at 6:04 PM, Darren Cook wrote: >> If the code was in pure C++, it would be trivial to have an object >> and then just pass a pointer to that object. I can't figure out how >> to do the same thing with R+Rcpp+inline. > > I asked myself a similar question a few weeks back (actually it came > from one of the questions at the end of the google talk [1] and, while > both Dirk and Romain confidently said it was possible, at the time I > couldn't see how to actually do it). > > I think what you're looking for is Rcpp::XPtr. I.e. you have your C++ > code allocate and *own* the memory, and then it passes it back to R by > wrapping it in XPtr. XPtr is a curious template as it does two distinct > tasks: it returns a C++ pointer to R, and it also turns an R object back > into a C++ pointer. > > Below is the proof-of-concept example I came up with. I use a custom > class (the real point of this example), but it could just as well be > std::vector. This example also shows a couple of other things: > > 1. Keeping the C++ class code in its own files. > > 2. Compiling two functions at once; this isn't necessary for this > example, it is just quicker. (test5b.R is also included below, and shows > how to do this with two separate compiler invocations.) > > (BTW, this example leaks memory. For long-running production code don't > forget that your C++ code owns the memory and is responsible for > deleting it.) > > Darren > > [1]: http://www.youtube.com/watch?v=UZkaZhsOfT4 > > > --------- test5.R --------------- > > library('inline') > > header=paste(readLines("test5.h"),collapse="\n") > src=paste(readLines("test5.cpp"),collapse="\n") > > use_src=' > Rcpp::XPtr< Example > xp(xp_); //I.e. Example xp=xp_; > return wrap(xp->a + xp->b); > ' > > fun=cxxfunction( > list(create=signature(),use=signature(xp_="externalptr")), > list(create=src,use=use_src), > includes=header, > plugin="Rcpp" > ); > > xp=fun$create() #xp is an Example object > print(xp) > print(fun$use(xp)) > > > -------- test5.h ------------------------ > > class Example{ > public: > int a,b; > > public: > Example(int a_,int b_):a(a_),b(b_){} > > }; > > using namespace Rcpp; > > > -------- test5.cpp ------------------------ > > Example *xp=new Example(10,20); > return XPtr<Example>(xp,true); > > > -------- test5b.R -------------------------- > > library('inline') > > header=paste(readLines("test5.h"),collapse="\n") > src=paste(readLines("test5.cpp"),collapse="\n") > > use_src=' > Rcpp::XPtr< Example > xp(xp_); //I.e. Example xp=xp_; > return wrap(xp->a + xp->b); > ' > > fun_create=cxxfunction( > signature(), > src, > includes=header, > plugin="Rcpp" > ); > > fun_use=cxxfunction( > signature(xp_="externalptr"), > use_src, > includes=header, > plugin="Rcpp" > ); > > xp=fun_create() #xp is an Example object > print(xp) > print(fun_use(xp)) > > > _______________________________________________ > 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
_______________________________________________ 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