Skip to content
Prev 6581 / 10988 Next

[Rcpp-devel] RcppOctave on Windows: testing needed

Le 08/10/13 17:12, Dominick Samperi a ?crit :
Sure. There is always the issue of linking against R, etc ... but this 
would eliminate the need for linking against Rcpp.

As for placing the client package in headers, not everything has to go 
there, I have e.g. some functions in Rcpp11 that are only defined in 
Rcpp11's .cpp file.

For example:

const char * type2name__impl(int sexp_type);

What I've done is making it so that Rcpp11's headers calls this one 
instead:

inline const char* type2name(int sexp_type){
	GET_CALLABLE(type2name__impl, sexp_type)
}

and all the magic is in the GET_CALLABLE macro:

#if defined(COMPILING_RCPP11)
#define GET_CALLABLE(__FUN__, ...) return __FUN__( __VA_ARGS__ ) ;
#else
#define GET_CALLABLE(__FUN__, ...)                          \
typedef decltype(__FUN__)* Fun ;                            \
static Fun fun = (Fun)R_GetCCallable( "Rcpp11", #__FUN__) ; \
return fun(__VA_ARGS__) ;
#endif

So if we are compiling Rcpp11 (which is true only for .cpp files in 
Rcpp11), then type2name would directly call type2name__impl, otherwise 
we first get the function pointer with :

static Fun fun = (Fun)R_GetCCallable( "Rcpp11", "type2name__impl" ) ;

and then call fun.

Writing this, I do realize that this in fact uses some C++11 features: 
variadic macros and decltype. It does not mean we could not do it in 
Rcpp, but it would be harder and would involve macro bloat (we would 
need something like GET_CALLABLE_0, GET_CALLABLE_1, GET_CALLABLE_2, ...

Then, when Rcpp11 dynamic library is loaded by R, the __impl function is 
registered:

#define REGISTER(__FUN__) R_RegisterCCallable( "Rcpp11", #__FUN__ 
"__impl", (DL_FUNC)__FUN__ ## __impl );

     REGISTER(type2name)

This allows me to have all in headers and use R's mechanism for 
"linking". Not really linking as it just involves resolving the function 
pointer.

I find this more maintainable than depending on each platform's linker.

Anyway, just saying a client package could use something similar so that 
it does not have to actually link.

Romain