[Rcpp-devel] Resolving NativeSymbolInfos from Rcpp

Romain Francois romain at r-enthusiasts.com
Wed Jun 9 07:46:38 CEST 2010


Le 09/06/10 07:14, Romain Francois a écrit :
>
> Le 09/06/10 03:04, Davor Cubranic a écrit :
>>
>> Hi there,
>>
>> I have a question about the murky world of R internals, DLLs, and
>> their interaction with Rcpp.
>>
>> There are some C routines in the 'stats' package that I would like to
>> call directly from my Rcpp-based package, e.g., loess_raw. However,
>> 'stats' only exposes them to R callers, not C or C++. (I.e., it does
>> not use R_RegisterCCallable, but they are among R_CMethodDef's passed
>> in R_registerRoutines.)
>>
>> Reading the information on writing R extensions, it sounds like there
>> may not be a way to get to the address of an object in another
>> package's DLL. (In this case, in stats.so.) However, there is a
>> NativeSymbolInfo for stats:::R_loess_raw, which includes all sorts of
>> info about the C method. Is there a way that this can be used to get a
>> function pointer to it from within my code? And if this is too
>> unportable, is there a cleaner way?
>>
>> Thanks,
>>
>> Davor
>
> Hi,
>
> I see
>
>  > getNativeSymbolInfo( "loess_raw" )
> $name
> [1] "loess_raw"
>
> $address
> <pointer: 0x103092820>
> attr(,"class")
> [1] "NativeSymbol"
>
> $package
> DLL name: stats
> Filename:
>
> /Library/Frameworks/R.framework/Resources/library/stats/libs/x86_64/stats.so
>
> Dynamic lookup: FALSE
>
> $numParameters
> [1] 24
>
> attr(,"class")
> [1] "CRoutine" "NativeSymbolInfo"
>
> So I'd probably look into the implementation of getNativeSymbolInfo
> (R_getSymbol in file Rdynload.c) and figure out what sort of pointer is
> the $address here. once you know that I suppose you can use it.
>
> There is a good chance the pointer is a DL_FUNC. You probably want to
> look at the Rdynpriv.h file too.
>
> Maybe this question is more suited to R-devel.
>
> Romain

After some more coffee, I came up with this:

require( Rcpp )
require( inline )

# borrowed from R private headers
# not part of R API, but does not change all that much
include <- '

typedef union {void *p; DL_FUNC fn;} fn_ptr;

DL_FUNC R_ExternalPtrAddrFn(SEXP s){
     fn_ptr tmp;
     tmp.p =  EXTPTR_PTR(s);
     return tmp.fn;
}

'

code <- '
	// grab loess_raw
	DL_FUNC loess_raw = R_ExternalPtrAddrFn( xp ) ;
	Rprintf( "loess_raw : <%p>\\n", loess_raw ) ;
	
	// call it
	// (*loess_raw)( ... )
	
	return R_NilValue ;
'

fx <- cxxfunction( signature( xp = "externalptr" ),
	code, include = include, plugin = "Rcpp" )
fx( getNativeSymbolInfo( "loess_raw" )$address )


Please expand the part that is actually suppose to call loess_raw and 
let us know if something useful happens.

It might be worth formalize that sort of things in a nice Rcpp 
abstraction. For example, make a Rcpp::DynamicLibrary class with member 
functions to pull these things conveniently.

Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/98Uf7u : Rcpp 0.8.1
|- http://bit.ly/c6YnCi : graph gallery collage
`- http://bit.ly/bZ7ltC : inline 0.3.5



More information about the Rcpp-devel mailing list