微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在C中调用R包中的C代码

是否可以在附加的C代码中从现有的R包中调用C(或C)函数

例如,我的包rje中的函数marginTable()使用相同名称的C函数.我想创建一个包含更多C代码的新包,其中一些可以使用marginTable()的C版本.我可以在新的C代码调用函数,而不仅仅是将C代码复制到新文件和包中吗?

或者使用这样的内部代码是不好的做法?

[各种各样的人都问过从另一个R包中调用已编译的代码,但是所有人都希望在R中进行,而不是使用C代码.

解决方法

所述R_RegisterCCallable / R_GetCCallable溶液指向@brodieG可能比下面的一个更好,至少当一个可以修改其中需要登记的包,并且其中的函数调用的选择是直接的(下面的例子中从多个 – 来或者更复杂的R代码,它选择几个函数之一传递给C,就像lapply的FUN参数一样,函数的选择在R中比C更容易实现.当想要公开/访问许多功能时,相关的是 Linking to other packages.

相关的可能性是使用R_init_rje.c中的类似内容在rje包中注册C函数

#include <Rinternals.h>
#include <R_ext/Rdynload.h>

SEXP rje(SEXP who) {
    Rprintf("Hello %s\n",CHAR(STRING_ELT(who,0)));
    return R_NilValue;
}

static const R_CallMethodDef callMethods[] = {
    {".rje",(DL_FUNC) &rje,1},{NULL,NULL,0}
};

void R_init_rje(DllInfo * info)
{
    R_registerRoutines(info,callMethods,NULL);
}

在NAMESPACE

useDynLib(rje,.registration=TRUE)

然后,在R as中可以获得C级入口点的地址

rje_c = getNativeSymbolInfo(".rje",PACKAGE="rje")

并且可以在其他包中使用它作为C函数的参数,例如,

.Call(.use_rje,rje_c$address,"A User")

#include <Rinternals.h>
#include <R_ext/Rdynload.h>

/* convenience deFinition of the function template */
typedef SEXP RJE_C_FUN(SEXP who);

SEXP use_rje(SEXP rje_c_fun,SEXP who) {
    /* retrieve the function pointer,using an appropriate cast */
    RJE_C_FUN *fun = (RJE_C_FUN *) R_ExternalPTraddr(rje_c_fun);
    return fun(who);
}

在包中说明这一点太笨拙了,但原理由以下文件rje.c说明

#include <Rinternals.h>
#include <R_ext/Rdynload.h>

/* convenience deFinition of the function template */
typedef SEXP RJE_C_FUN(SEXP who);

SEXP rje(SEXP who) {
    Rprintf("Hello '%s'\n",0)));
    return R_NilValue;
}

SEXP use_rje(SEXP rje_c_fun,using an appropriate cast */
    RJE_C_FUN *fun = (RJE_C_FUN *) R_ExternalPTraddr(rje_c_fun);
    return fun(who);
}

static const R_CallMethodDef callMethods[] = {
    {".rje",{".use_rje",(DL_FUNC) &use_rje,2},NULL);
}

使用R CMD SHLIB rje.c编译,并使用as

> dyn.load("rje.so")
> .Call(".use_rje",getNativeSymbolInfo("rje")$address,"A User")
Hello 'A User'
NULL

原文地址:https://www.jb51.cc/c/118670.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐