[Rd] passing pointer types via .C calls

Luke Tierney luke@stat.umn.edu
Mon, 5 Mar 2001 09:17:03 -0600 (CST)

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


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 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