[Rcpp-devel] "binding" Rcpp::InternalFunction or Rcpp::CppFunction

Christian Authmann authmanc at Mathematik.Uni-Marburg.de
Fri Aug 1 13:17:13 CEST 2014


Hello,

I'd like to do something similar to

Foo getdata(DataProvider *p, int id) {
   return p->getData(id);
}

DataProvider provider(/* arguments specifying data source*/);
RInside R;
R["getdata"] = Rcpp::InternalFunction( std::bind(getdata, &provider) );


The idea is that I can export a getter for each available provider and 
the R script will pick the correct one just by calling the correct function.

id <- 42
d <- getdata(id)

Of course the code above won't work, since CppFunction uses plain 
function pointers instead of std::function - there's no way to turn a 
bind'ed std::function back into a function pointer. And we cannot use 
c++11's std::function in rcpp since CRAN won't allow it (or did that 
change?)


So instead I tried the old "userdata"-idiom, where you pass a void* to 
the wrapper, which gets passed back as a parameter when calling. I added 
a bunch of CppFunction implementations. They take the userdata-pointer 
in their constructor and store it, and on operator() the 
userdata-pointer is passed as the first argument. For example:
------- snip -------
template <typename RESULT_TYPE, typename U0>
class CppFunctionWithUserdata1 : public CppFunction {
	public:

		CppFunctionWithUserdata1(RESULT_TYPE (*fun)(void*,U0) , void 
*userdata, const char* docstring = 0) : CppFunction(docstring), 
ptr_fun(fun), ptr_userdata(userdata) {}

		SEXP operator()(SEXP* args) {
			BEGIN_RCPP
			typename traits::input_parameter< U0 >::type x0(args[0]);
			return Rcpp::module_wrap<RESULT_TYPE>(ptr_fun(ptr_userdata, x0));
			END_RCPP
		}

		inline int nargs() { return 1; }
		inline void signature(std::string& s, const char* name) { 
Rcpp::signature<RESULT_TYPE,U0>(s, name); }
		inline DL_FUNC get_function_ptr() { return (DL_FUNC)ptr_fun ; }

	private:
		RESULT_TYPE (*ptr_fun)(void*,U0) ;
		void *ptr_userdata;
};
------- snip -------

With another constructor to InternalFunction, I can now do:
R["getdata"] = Rcpp::InternalFunction( getdata, (void *) &provider );

which compiles and works just fine. (as long as getdata() adds a cast 
back from void* to DataProvider*)

But I don't know if this is safe to do, because CppFunction can return a 
plain function pointer in get_function_ptr(), and that will point to a 
function which neither matches the signature() nor the nargs().

get_function_ptr() is a public method, and will also be exported via the 
public interface in modules/Module.h
So if someone grabs that function pointer and tries calling it 
themselves instead of using CppFunction::operator(), things will blow 
up. Is it likely that someone, somewhere does something like that?


So what's the way forward?

a) screw it, nobody but me needs this feature and it won't be committed 
anyway

b) it's safe, I'll get it fleshed out and try submitting a pull request 
to rcpp-scripts and rcpp

c) it's unsafe and unfeasible to do

d) it's unsafe. Instead I'll try to create a new class similar to 
CppFunction, but without exporting a function pointer or depending on 
Module.h - or maybe integrating the functionality into InternalFunction 
itself, so it won't need to delegate to another class. I don't yet know 
enough to say if this is feasible.

e) some other approach you'll advise me of ;)


Thanks again for your help,
Christian


-- 
Christian Authmann
Philipps-Universität Marburg
Fachbereich Mathematik und Informatik
AG Datenbanksysteme
Hans-Meerwein-Straße
D-35032 Marburg


More information about the Rcpp-devel mailing list