[Rd] Problem with new("externalptr")

Herve Pages hpages at fhcrc.org
Wed Jan 30 00:40:32 CET 2008


Hi,

It seems that new("externalptr") is always returning the same instance, and
not a new one as one would expect from a call to new(). Of course this is hard
to observe:

  > new("externalptr")
  <pointer: (nil)>
  > new("externalptr")
  <pointer: (nil)>

since not a lot of details are displayed.

For example, it's easy to see that 2 consecutive calls to new("environment")
create different instances:

  > new("environment")
  <environment: 0xc89d10>
  > new("environment")
  <environment: 0xc51248>

But for new("externalptr"), I had to use the following C routine:

  SEXP sexp_address(SEXP s)
  {
        SEXP ans;
        char buf[40];

        snprintf(buf, sizeof(buf), "%p", s);
        PROTECT(ans = NEW_CHARACTER(1));
        SET_STRING_ELT(ans, 0, mkChar(buf));
        UNPROTECT(1);
        return ans;
  }

Then I get:

  > .Call("sexp_address", new("externalptr"))
  [1] "0xde2ce0"
  > .Call("sexp_address", new("externalptr"))
  [1] "0xde2ce0"

Isn't that wrong?

I worked around this problem by writing the following C routine:

  SEXP xp_new()
  {
        return R_MakeExternalPtr(NULL, R_NilValue, R_NilValue);
  }

so I can create new "externalptr" instances from R with:

  .Call("xp_new")

I understand that there is not much you can do from R with an "externalptr"
instance and that you will have to manipulate them at the C level anyway.
But since new("externalptr") exists and seems to work, wouldn't that be
better if it was really creating a new instance at each call?

Thanks!
H.



More information about the R-devel mailing list