Richard Beare wrote:> Hi,
> this relates to my earlier message about external references and
> finalizers. I was experimenting over the weekend and now suspect that
> the appropriate solution to my problem will be to have a special case in
> the code that handles the .C call so that external references are
> handled appropriately - I guess that a pointer to the reference should
> be passed to the C code. As I've never experimented with the R
internals
> before I thought that I had better check peoples opinion. Does this
> approach break anything in the work the Luke Tierney has been doing?
> I've only had a quick look so far so I'm not really certain how the
code
> that handling the .C call is meant to work. I have successfully passed
> the pointer to the external reference to my code, but I'm really not
> sure about how the conventions used for this kind of thing - who should
> I be talking to about it?
>
> All advice welcome....
>
I am a little confused about exactly how you are doing things but
maybe the following will help. Or not :-)
To let the R memory manager manage your external object you need to
create a *single* R object that represents your external one
only reference your external object through its R representative
That way once the memory manager finds that it is not possible to
access the R representative from R any more the it knows that it is
safe for your external object to be reclaimed, using say the
reclamation code you register as a finalizer.
In languages like Java where objects are passed by reference there
isn't much more to it--any object can have a finalizer attached to it
(either via a finalize mehtod or using the weak reference mechanism).
In R things are a bit more complicated because (most) objects are
passed by value. So if you do
x <- some calculation that yields a numeric
...
y <- x
then all that is guaranteed is that y refers to a value with the same
numeric contents (and attributes and the like) but not necessarily to
the same physical object in memory. It might be the same or it might
be a copy. So if you represent your external object as a numeric
containing some encoding of the pointer value and do
x<-NewExternalObject()
...
y<-x
then y will contain the same pointer value but may not reference the
same internal R object. If it does not, and there are no more
references to the original object, and a finalizer was attached to the
original object, then your external object may have been reclaimed
before you use y, and then .... Using a standard numeric object to
represent external objects means you cannot quarantee that there is a
*single* R object to represent your external one.
This is the reason for a special external pointer object. These
things are never copied, they are passed by reference. (There are a
few other objects that are also always passed by reference:
environments and symbols). This guarantees the one-to-one
correspondence between the R representation and the external object
that you need to get the memory management to work.
How you get things from C to R and back (.Call, .C, whatever) doesn't
really matter. What matters is that you use a representation in R
that will be passed by reference.
Hope that helps
luke
--
Luke Tierney
University of Minnesota Phone: 612-625-7843
School of Statistics Fax: 612-624-8868
313 Ford Hall, 224 Church St. S.E. email: luke@stat.umn.edu
Minneapolis, MN 55455 USA WWW: http://www.stat.umn.edu
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To:
r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._