On Jun 4, 2011, at 10:31 AM, [email protected] 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
>
> ______________________________________________
> [email protected] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel