On Jun 4, 2011, at 10:31 AM, soeren.vo...@uzh.ch wrote: > Hello > > Apologies for cross-posting, the discussion should (if) go to R-devel, but I > also want to reach the rcpp-devel people. > > My C++ class FOO is a module available through Rcpp, and it works fine and is > -- so far -- bug free. With trying to further develop my R package, I thought > it was a good idea to interface my C++ workhorse FOO with an S4 class Foo. > After some long and not always insightful trip through S4 classes and > methods, I am not sure if I am on the right way of thinking and designing. > Since there is no local assistance available, could you help to make things > clearer? > > Just a brief outline: > > FOO is the C++ object, and Foo should be the S4 class. If the user creates an > object, say bar, from class Foo, the creation process automatically makes a > new FOO object relating to bar in that a unique name of the FOO instance is > stored in a slot of bar. All the user then has to do is modify bar by simple > assignments. The getters and setters ("$", "[") are set up and work. Each > modification goes in hand with assigning new values to bar as well as > updating the FOO object through available setters from FOO. >
It's fairly simple, you just create an external pointer for your object, register "delete obj;" as its finalizer and put it in a slot of your S4 object . Have a look, for example, at rJava. It uses S4 objects with one slot being an external pointer to the object in Java (in your case C++). For a C++ package with external pointers see Acinonyx (aka iPlots eXtreme) - from RCalls.cpp: static void AObjFinalizer(SEXP ref) { if (TYPEOF(ref) == EXTPTRSXP) { AObject *o = static_cast<AObject*> (R_ExternalPtrAddr(ref)); if (o) o->release(); // NOTE: you would probably use delete o; instead } } SEXP A2SEXP(AObject *o) { SEXP xp = R_MakeExternalPtr(o, R_NilValue, R_NilValue); R_RegisterCFinalizerEx(xp, AObjFinalizer, TRUE); return xp; } AObject *SEXP2A(SEXP o) { if (TYPEOF(o) != EXTPTRSXP) Rf_error("invalid object"); return (AObject*) R_ExternalPtrAddr(o); } > So far, this way has brought me to about 100 lines, but now I read about > ReferenceClasses and was wondering, if there is a much easier way of > achieving my goals. Moreover, I was not sure any longer if my goals make > sense or if a more advanced programmer would do it totally different (and > could share some structural thinking on their approach). > ReferenceClasses are very similar - they differ from the approach I described only in that they use an environment for the reference semantics where your would use external pointer to your object. Technically, you could put your external pointer in a reference class object - what you would gain is the ability to store other R objects alongside if you need them. > The idea behind my way of doing was based upon several considerations. First, > a "classical" R object would not confuse users, as I assume users of my > package to be rather non-skilled (and not willing to change that). Second, I > want to create a properly programmed package for distribution on CRAN and > publication, eventually. Third, I want to save objects across sessions. So if > a user restores a session, a simple command, say, restore(), would do the > trick to build all the related C++ objects again. However, I admit that I > still have not figured out how to automatically clean up the workspace > correctly before leaving a session, wanted or unwanted, that is, clean up > memory before leaving home. Again, have a look at rJava (see ?.jcache) - it uses Java object serialization to cache serialized versions of objects (as raw vectors) in the protection part of the pointer which gets serialized by R on save(). Then restoration is automatic: when rJava sees a NULL pointer (that's what the are deserialized too) in the S4 object, it checks whether there is a serialized cache and restores the Java object. Cheers, Simon > Fourth, pure arithmetic check is done in C++, however, semantic check > *should* be left to R, and the validity and class routines seem to be perfect > for this. Fifth, some work should be done in R, such as the passing of data > frames or samples from distributions. > > I hope to get some structured ideas and hints how to start and/or proceed. > > Thank you in advance, > Sören > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > > [[alternative HTML version deleted]]
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel