[Rcpp-devel] Fwd: Re: Making objects in the C++ "side" persistent

Martin Jakt mjakt at z2.keio.jp
Mon Jun 16 07:59:02 CEST 2014


(sorry Dirk, I forgot to include the mailing list in my previous posting,
so here is another copy).


Hi Dirk,

I've not yet found a solution to my problem, but have been trying to get my 
head around some of the magic that Rcpp does, and have a few questions I'd 
appreciate a pointer to.

 
> | I don't really mind to lose the information within the objects and am just
> | looking for some way to avoid R trying to access invalid pointers after a
> | reload. My thought was to somehow subvert the 'save' process such that the
> | pointer address is not written. Can this be done? I tried to set the
> | serialize() function for the class, but this seems not to be used by
> | save().
> I think this is the right route.  And we now have access to serialize() from
> the C/C++ side (via the small package RApiSerialize which I used in
> RcppRedis). It should not be too hard to move towards something like
> saveRDS/readRDS. Maybe you can experiment with explicitly deserialization
> of the 'payload' of your object, and then recreate it?
> 

RApiSerialize looks nice, but how can you get the save() function to call it 
(or any other serialize function)? From what I can work out save() doesn't 
seem to make use of serialize functions, but instead uses it's own 
serialization.

> | The behaviour I would be happy with, is something similar to what you get
> | with RMySQL connections. These (understandably) get dropped between
> | sessions, and need to be recreated by calling the constructor.
> | 
> | I would appreciate any advice or pointers. I've tried searching the
> | documentation for answers, but have failed to find anything that I can
> | find.
> There were some old discussions when Modules was new and fresh, but nobody
> has worked out a solution.  It should be doable, though, or at least
> "approximatively".  But we can rely on just 'save' or 'saveImage'.  We need
> to do the extra step.

(The following is a bit on the long side, but is primarily me describing what 
I think is going on, to hopefully have any gross misunderstandings pointed 
out.)

I tried to read up on the documentation for the save() function to see if I 
could come up with something usable. From the documentation, it states that 
external pointers are saved as null pointers, so I went looking for the 
externalPointer defined by the Module. This led me to the following 
(mis?)understanding:

when I use new() to make a new Rcpp module object representing a C++ class, 
this creates an S4 object that contains an environment in the .xData slot.

This environment contains a set of external pointers which are used by the 
methods of the S4 object created.

The environment also contains refMethodDef objects for external functions that 
have been called at least once.

Which sort of brings me to my question:

If I have an object called ds1, which has a member function called squeeze, 
Rcpp modules sets up the R environment so that I can call this easily by 
doing:

ds1$squeeze(2, 1000)

which will actually call:

ds1 at .xData$squeeze( )

or at least sets up a link between these two.

If I save and reload the session, the external pointers are indeed set to 
null, as they should be. And if I try to call:

ds1 at .xData$squeeeze()

after reloading that fails with an error. Which is the behaviour I'm looking 
for. However, if I call ds1 directly with anything, or 
ds1$squeeze()

or even, just try to use tab completion on ds1, then R crashes immediately.

So, I'm trying to understand how Rcpp module maps the '$' to call module 
functions. 

>From the Rcpp module vignette example:

setMethod("$", "Uniform", function(x, name) {
	function(...) .Call( Uniform_method(name), x at pointer, ... )
})

and in Module.R more generally:

setMethod("$", "C++Class", function(x, name) {
	assign("pointer", value, environment = as.environment(module))
	value
}

>From my limited understanding of setMethod, this should result in a function 
called '$' that takes a "C++Class" as a function. But in this case it gives me 
a way to call

object_name$function()

I'm trying to understand how that works, but can't find anything that seems 
relevant. Do you have any suggestions as to where I can find documentation for 
this behaviour (eg. does '$' have special meaning here?).

What I'd like is simply to have the object$function() first check the value of 
.xData$pointer, to make sure it is not null before proceeding. But can't 
really get any further without understanding what Rcpp Module is doing.

thanks for reading this far,

cheers,

Martin

-- 
Martin Jakt
Department of Systems Medicine
Mitsunada Sakaguchi Laboratory
Keio University School of Medicine
-----------------------------------------
-- 
Martin Jakt
Department of Systems Medicine
Mitsunada Sakaguchi Laboratory
Keio University School of Medicine


More information about the Rcpp-devel mailing list