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

Reply via email to