R:指向c函数的指针 [英] R: pointer to c function

查看:123
本文介绍了R:指向c函数的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从C代码将函数的指针传递给R(使用外部R),以及如何从R调用该函数之后??

How to pass a pointer to a function from C code to R (using External R) and after call that function from R??

类似的东西:

C:

typedef void (* FunctionPtr)();
SEXP ans;
PROTECT(ans = /* ?some code? */);
R_tryEval(ans, R_GlobalEnv, NULL);
UNPROTECT(1);

R:

callback_function()

@Romain Francois的帖子很有帮助.
myapp代码:

@Romain Francois's post was very helpful.
myapp code:

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);
    }
};

R和Rcpp
script.R

###################
sourceCpp("utils.cpp")
###################
callback <- function()
{
  callCallback()
}

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;
}

推荐答案

外部指针是您想要的.它们使您封装了指向任意数据结构的指针. 数据一词在这里很重要,而函数指针则是另一种野兽.如果要使用C++Rcpp,我建议创建一个封装函数指针的小类:

External pointers are what you are looking for. They ley you encapsulate pointers to arbitrary data strucures. The word data is important here and function pointers are a different beast. If you want to use C++ and Rcpp, what I would suggest is to create a small class that encapsulates the function pointer:

typedef void (* FunctionPtr)();
class FunctionPointer {
  FunctionPtr ptr;
public:
    FunctionPointer( FunctionPtr ptr_) : ptr(ptr_){}
} ;

,然后创建一个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() ;
}

在R端,您可以使用词法作用域,例如将外部指针包装到R函数中:

On the R side, you can use lexical scoping for example to wrap the external pointer into an R function:

callback <- local( {
    ptr <- create_ptr()
    function(){
        invokeCallback( ptr )
        invisible(NULL)
    } 
} )
callback()

这篇关于R:指向c函数的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆