And*_*rii 4 c++ pointers r rcpp
如何将指向函数的指针从C代码传递给R(使用外部R)并在调用该函数后从R ??
就像是:
C:
typedef void (* FunctionPtr)();
SEXP ans;
PROTECT(ans = /* ?some code? */);
R_tryEval(ans, R_GlobalEnv, NULL);
UNPROTECT(1);
Run Code Online (Sandbox Code Playgroud)
R:
callback_function()
Run Code Online (Sandbox Code Playgroud)
编辑:
@Romain Francois的帖子非常有帮助.
myapp代码:
namespace
{
void callback()
{
std::cout << "callback\n" << std::flush;
}
}
class Worker
{
public:
/*...*/
void initialize(argc, argv)
{
Rf_initEmbeddedR(argc, argv);
SEXP ans, val;
typedef void (* FunctionPtr)();
PROTECT(ans = Rf_lang2(Rf_install("source"), Rf_mkString("script.R")));
R_tryEval(ans, R_GlobalEnv, NULL);
UNPROTECT(1);
PROTECT(val = Rf_ScalarInteger((int)(&callback)));
/* pass the address of the pointer to a function */
PROTECT(ans = Rf_lang2(Rf_install("setCallback"), val));
R_tryEval(ans, R_GlobalEnv, NULL);
UNPROTECT(2);
}
void uninitialize()
{
Rf_endEmbeddedR(0);
}
};
Run Code Online (Sandbox Code Playgroud)
R和Rcpp
脚本.R
###################
sourceCpp("utils.cpp")
###################
callback <- function()
{
callCallback()
}
Run Code Online (Sandbox Code Playgroud)
utils.cpp
#include <Rcpp.h>
using namespace Rcpp;
typedef void (* Callback)();
static Callback spCallback = 0;
// [[Rcpp::export]]
void callCallback()
{
if (spCallback) {
spCallback();
} else {
Rprintf("ERROR: callback is not set");
}
}
// [[Rcpp::export]]
void setCallback(const int address)
{
spPlaceOrder = (Callback)address;
}
Run Code Online (Sandbox Code Playgroud)
外部指针是你正在寻找的.他们会让你封装指向任意数据结构的指针.单词数据在这里很重要,函数指针是不同的野兽.如果你想使用C++和Rcpp,我的建议是建立一个小的类,它封装函数指针:
typedef void (* FunctionPtr)();
class FunctionPointer {
FunctionPtr ptr;
public:
FunctionPointer( FunctionPtr ptr_) : ptr(ptr_){}
} ;
Run Code Online (Sandbox Code Playgroud)
然后创建一个XPtr<FunctionPointer>:
#include <Rcpp.h>
using namespace Rcpp ;
// your callback function
void callback(){
Rprintf( "hello from callback\n" ) ;
}
// The function that creates an external pointer to your
// callback
// [[Rcpp::export]]
XPtr<FunctionPointer> create_ptr(){
return XPtr<FunctionPointer>( new FunctionPointer(callback) );
}
// The function that invokes the callback
// [[Rcpp::export]]
void invokeCallback( XPtr<FunctionPointer> callback){
callback->ptr() ;
}
Run Code Online (Sandbox Code Playgroud)
在R端,您可以使用词法作用域将外部指针包装到R函数中:
callback <- local( {
ptr <- create_ptr()
function(){
invokeCallback( ptr )
invisible(NULL)
}
} )
callback()
Run Code Online (Sandbox Code Playgroud)