[Rd] Finalization and external pointer objects

Richard Beare Richard.Beare@cmis.csiro.au
Fri, 02 Mar 2001 10:19:56 +1100


Hi,

I've been developing an image analysis package based on R for a while
now and I've had problems relating to garbage collection, so it with
great interest that I've noticed the work done by Luke Tierney in this
area, and I'd like to discuss how best to fit it into my package. I'll
start with how my package is structured - an image is represented by an
integer with a class of "image". This is actually a pointer to a C
abstract data type. Most imaging functions in my library have a form
like this


IMAGE *imquickthresh(const IMAGE *src, IMAGE *target, float p1, int p2);

the target parameter is optional and never used from R.

This is made appropriate for a .C call like this

Rimquickthresh(IMAGE **output, IMAGE **src, Sfloat *p1, Sint *p2)
{
  IMAGE *dummy;

  dummy = imquickthresh(*src, NULL, (float)(*p1), (int)(*p2));

  *output = dummy;
}

the R code calling this looks like

function(src, p1, p2)
{
  if (!is.image(src))
    stop("Parameter 'src' should be an image.")
  output <- POINTER
  output<-.C("Rimquickthresh", val = output, (src), as.double(p1),
as.integer(p2))$val
  if (output == POINTER)
    return(0)
  class(output) <- c("image")
  AddGlobalImageFunc(output)
  output
}


The AddGlobalImageFunc is related to my GC mechanism.
POINTER is as.integer(0) or as.double(0), depending on platform.

This is mostly generated automatically. I'd really like to discard my GC
mechanism and make use of the special facilities that are being
developed. So far it seems that most of these are related to the .Call
mechanism, so is there a sensible way to use them with pointers passed
to or returned from a .C call? I'd like to avoid changing everything to
make use of the .Call facility because I suspect it might make porting
to Splus more difficult and it's likely to be a significant amount of
work.

I'm guessing that there needs to be some of the following functions at
the R level - perhaps they are already around and I've missed them.

GenExtPointer - basically the same thing that can get returned by a
.Call using  R_MakeExternalPtr. The address of the appropriate part of
this would then need to be passed in the place of "output" above,
presumably by using an R interface to R_ExternalPtrAddr.

register.finalizer mentioned in Lukes discussion papers is needed.

I welcome any advice about other ways of approaching this problem,
indications of where the development of these things are at and if there
is ever likely to be any hope of using similar functionality under
Splus? Are the results from an approach based on .C going to be so
horrible that I should just give up and work on a .Call based approach?


I look forward to hearing from you.

-- 
Richard Beare, CSIRO Mathematical & Information Sciences
Locked Bag 17, North Ryde, NSW 1670, Australia
Phone: +61-2-93253221 (GMT+~10hrs)  Fax: +61-2-93253200

Richard.Beare@cmis.csiro.au
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._