Hi again, Here is an example of an annoyance that I think is directly related to the problem with new("externalptr"). When you try to extend the "externalptr" class:
> setClass("ExternalInteger", contains="externalptr") [1] "ExternalInteger" then every call to new("ExternalInteger") will return the same instance too. I've tried to define an "initialize" method for "ExternalInteger" objects, but, whatever I do, I end up with the same "ExternalInteger" instance. So in the end I had to define the "ExternalInteger" class this way: > setClass("ExternalInteger", representation(xp="externalptr")) even if I'd really like to be able to use the "is a" semantic and not the "has a" semantic. Then I use my xp_new() C routine (see previous post) for initializing the xp slot: setMethod("initialize", "ExternalInteger", function(.Object, ...) { [EMAIL PROTECTED] <- .Call("xp_new") ... .Object } ) Then everytime I need to pass an "ExternalInteger" instance x to a C routine, I need to perform one extra step to reach the externalptr (need to pass [EMAIL PROTECTED] to the routine instead of x itself). So unfortunately, things are quite ugly and more painful than necessary. Thanks, H. Herve Pages wrote: > 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. > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel