Re: [Rd] Passing externalptr to .C()

From: Prof Brian Ripley <ripley_at_stats.ox.ac.uk>
Date: Thu, 17 May 2012 13:37:25 +0100

On 16/05/2012 23:30, Rick Sayre wrote:
> Thanks very much for the quick reply.
>
> I'd like to avoid static state in the .so, which is why I'm using
> the opaque pointer. It is indeed possible to convert everything to
> .Call(), but the work seems unnecessary given that it used to work
> just fine and I am going out of my way to pass things with correct
> type conversion and semantics. Again, this seems like exactly the
> usage externalptr was designed for, doesn't it?
>
> It seems I can avoid the warnings by putting the externalptr in
> a list:

Actually, 'Writing R Extensions' says:

  .. external pointers should only be used as part of an object with normal semantics, for example an attribute or an element of a list.

so that *is* the 'correct semantics' ....

> getDeviceInfo<- function(handle) {
> .C("groovyDevice_getDeviceInfo", PACKAGE="groovyDevice",
> list(handle), # Avoid pedantic warnings via encapsulation
> status = as.integer(0))[-1] # skip handle
> }

> void
> groovyDevice_getDeviceInfo(SEXP *handle, int *status)
> {
> groovyHandle *gh = R_ExternalPtrAddr(*handle);
> *status = GroovyStatus(gh);
> }

> Perhaps this will help others in the same boat in which I find myself.

As has been said here many times recently, .C is an old (some say obselete) interface, and pre-dates objects such as external pointers. It was chance that this ever worked: it was never designed to.

If you find yourself with C[++] code which uses Rinternals.h it should use the .Call/.External interfaces, and there is no guarantee that using .C for such things will continue to work (as it is all too easy to break R's copying semantics and corrupt loaded R code).

> Cheers
>
> --Rick
>
> On 05/11/2012 03:34 PM, Duncan Murdoch wrote:
>> On 12-05-11 5:20 PM, Rick Sayre wrote:
>>> Greetings.
>>>
>>> 2.15.0 added this behavior
>>> http://developer.r-project.org/blosxom.cgi/R-devel/NEWS/2012/03/29#n2012-03-29
>>>
>>>
>>>
>>> o Passing R objects other than atomic vectors, functions, lists and
>>> environments to .C() is now deprecated and will give a warning.
>>> Most cases (especially NULL) are actually coding errors. NULL
>>> will be disallowed in future.
>>>
>>>
>>> This seems to make sense, except that this case includes externalptrs.
>>>
>>> I have quite a bit of code, designed to interface with various
>>> external hardware devices, which uses this sort of idiom:
>>>
>>> # for example
>>> getDeviceInfo<- function(handle) {
>>> .C("groovyDevice_getDeviceInfo", PACKAGE="groovyDevice",
>>> handle,
>>> status = as.integer(0))[-1] # skip handle
>>> }
>>>
>>> where "handle" was the result of a .Call to a routine which
>>> returned a SEXP which was the result of a R_MakeExternalPtr() call
>>>
>>> The "c" routine looked like:
>>> void
>>> groovyDevice_getDeviceInfo(SEXP handle, int *status)
>>> {
>>> groovyHandle *gh = R_ExternalPtrAddr(handle);
>>> *status = GroovyStatus(gh);
>>> }
>>>
>>> This all used to work fine. As of 2.15.0, I now get this:
>>> Warning message:
>>> In getDeviceInfo() :
>>> passing an object of type 'externalptr' to .C (arg 1) is deprecated
>>>
>>> Passing the same handle to a .Call() does [of course] work fine.
>>>
>>> I thought my usage was exactly as designed. How then should I be
>>> passing an externalptr to a .C() call?
>>
>> I think you shouldn't be doing that. You should be using .Call.
>>
>> If your code can handle external pointer objects (as in the example),
>> this should be an easy transition. I haven't tested this, but I think
>> the conversion to the .Call interface (less error checking) is simply
>>
>> SEXP_getDeviceInfo(SEXP handle, SEXP status)
>> {
>> groovyHandle *gh = R_ExternalPtrAddr(handle);
>> INTEGER(Sstatus)[0] = GroovyStatus(gh);
>> return R_NilValue;
>> }
>>
>>
>> If your code is using the pointer just as an opaque handle, I'd suggest
>> keeping an array of them, and pass an index into that array: then .C
>> will be fine.
>>
>> Duncan Murdoch
>
> ______________________________________________
> R-devel_at_r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Brian D. Ripley,                  ripley_at_stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Thu 17 May 2012 - 12:42:37 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 17 May 2012 - 13:01:17 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive