Skip to content
Prev 2417 / 10988 Next

[Rcpp-devel] [Rd] Interfacing a C++ class

On Jun 4, 2011, at 10:31 AM, soeren.vogel at uzh.ch wrote:

            
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);
}
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.
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110604/e99936bb/attachment.htm>