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

From: Rick Sayre <whorfin_at_pixar.com>
Date: Wed, 16 May 2012 15:30:37 -0700

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:

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.

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 Received on Thu 17 May 2012 - 11:30:16 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 - 12:51:32 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