Thanks to Wush Wu. I think I now find the answer to the question by using RCPP_EXPOSED_CLASS_NODECL
One note is that I have to use Rcpp::internal::make_new_object to create the S4 object, instead of Rcpp::wrap. Because current wrap do copy-construct from an existing object to a new pointer. While in my case, doing so will trigger the destructor of the class to free the arrays, and a explicit copy is needed . So what I did is return a Rcpp::internal::make_new_object(new MyClass()); Which works for my case. But it sounds a bit undesirable as the function is marked as internal. Any suggestions? Tianqi On Tue, Oct 6, 2015 at 6:51 PM, Tianqi Chen <tianqi.tc...@gmail.com> wrote: > Oh, the question is not about supporting native Save/Load from R. I > understand the hardness of that due to no customized loader from external > pointer. The function listed here aims to write a customized function like > ```save.list``` instead of R's native save/load, which is doable. The > question is how to get the underlying external ptr from an Rcpp > class_<MyClass> Object, within the life cycle of the R session. Sorry about > the confusion. > > Let me rephrase the question in this way: I want to implement a > customized element-wise sum of a List of GPUArray object, which I exposed > using Rcpp Module class. However, in order to do that, I need to somehow > get the external Pointer of GPUArray from the S4 object, to redirect the > call to InternalSumOnGPU function. > > After the computation, we need to wrap(construct) a new GPUArray S4 object > from C++ side(what was normally provided was constructor from R side). > > ``` > class GPUArray { > public: > static SEXP Sum(SEXP list) { > Rcpp::List data_lst(list); > std::vector<GPUArray *> internals(data_lst[i]); > for (size_t i = 0; i < data_lst.size(); ++i) { > SEXP obj = data_lst[i]; > // Need to Get internal pointers from S4 GPUArray object > internals[i] = GetPtr<GPUArray>(obj); > } > GPUArray *ret = InternalSumOnGPU(internals); > // need to return the S4 object > return class_<GPUArray>(ret); > } > > }; > > RCPP_MODULE(GPUArray) { > class_<GPUArray>("GPUArray"); > > function("gpu.sum", &GPUArray::Sum); > } > ``` > > > Tianqi > > On Tue, Oct 6, 2015 at 5:55 PM, Dirk Eddelbuettel <e...@debian.org> wrote: > >> >> On 6 October 2015 at 14:40, Tianqi Chen wrote: >> | Dear Rcpp Developers: >> | >> | ```c++ >> | class MyClass { >> | public: >> | static void SaveList(SEXP list, const std::string& filename) { >> | Rcpp::List data_lst(list); >> | std::vector<MyClass *> internals(data_lst[i]); >> | for (size_t i = 0; i < data_lst.size(); ++i) { >> | SEXP obj = data_lst[i]; >> | // Need to Get internal pointers from S4 MyClass object >> | internals[i] = GetPtr<MyClass>(obj); >> | } >> | SomeRealSave(internals, filename); >> | } >> | static void LoadList(const std::string& filename) { >> | std::vector<MyClass > internals; >> | SomeReadLoad(&internals); >> | Rcpp::List out(internals.size()); >> | for (size_t i = 0; i < internals.size(); ++i) { >> | // need to construct a MyClass object from C++ side >> | out[i] = MyClassConstructor(internals[i]); >> | } >> | return out; >> | } >> | }; >> | >> | RCPP_MODULE(MyClass) { >> | class_<MyClass>("MyClass"); >> | >> | function("save.myclass.list", &MyClass::SaveList); >> | function("load.myclass.list", &MyClass::LoadList); >> | } >> | ``` >> | >> | To be specific, We have ways to Save/Load the pointers to the MyClass >> object >> | (in the SomeRealSave and SomeRealLoad). In our specific use-case, It >> was an >> | Array on GPU. >> >> As I recall, we had several discussions here a few years ago about the >> impossibility of serialising Module objects to disk. In short, you >> can't. You write out a bunch of ram which you can re-read, but that >> doesn't >> make an object. >> >> You will have to rebuild the objects at the next run time so that memory >> is >> allocated and correctly pointed to. >> >> See here for one such prior email: >> >> http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2014-May/007539.html >> >> and an older one >> >> http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-April/002107.html >> >> | So the question is how is there any solution to GetPtr<MyClass> and >> | MyClassConstructor, so we can get the internal pointer of MyClass from >> SEXP >> | (which is the S4 object), and construct the corresponding S4 object >> given the >> | information of MyClass. >> | >> | What was wanted is indeed possible if we choose to only expose >> XPtr<MyClass>, >> | so we can simply do >> | ``` >> | MyClass * GetPtr<MyClass>(SEXP obj) { >> | XPtr<MyClass>(obj).get(); >> | } >> | MyClassConstructor(MyClass *ptr) { >> | return XPtr<MyClass>(ptr); >> | } >> | >> | ``` >> | >> | But it would be really nice we can directly return a wrapped S4 object >> instead >> | of raw ptr >> >> Yes, it would be -- but that doesn't meam it is possible under the current >> framework. >> >> Sorry, Dirk >> >> -- >> http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org >> > >
_______________________________________________ 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