繁体   English   中英

如何从C API保存R对象

[英]How to save R object from C API

我基本上需要将R表达式保存到文件中

save( x, file="myfile.Rdata")

但是,我需要从C / C ++ API中执行此操作(因为“ x”的值是由C ++函数求值的,因此将其作为R的插件加载)。 在网上研究了问题之后,没有找到任何有用的东西,我去研究了一下代码,发现src / main / saveload.c中有一个函数“ do_save”。

SEXP attribute_hidden do_save(SEXP call, SEXP op, SEXP args, SEXP env)

那是.Internal,当我在R中键入“保存”时,可以完成所有工作,但是显然我无法正确地将生成的插件与R链接,我得到了错误消息:

> dyn.load( "Plugin.so" )
Error in dyn.load("new-plugin/Plugin.so") :
  unable to load shared object 'Plugin.so':
  Plugin.so: undefined symbol: _Z7do_saveP7SEXPRECS0_S0_S0_

一般来说,应该如何在C API中使用这些内部函数,换句话说,应该如何从C API中评估内置R函数?

当你写一个C ++函数,在二进制文件中的函数名被更改或“ 错位 ”,允许函数重载工作。 为避免这种情况,可以使用extern "C" ,如果您实际上并没有使用任何c ++特定的语法或功能,请使用ac编译器。

对于第一个修复,它会像这样,

extern "C" SEXP attribute_hidden do_save(SEXP call, SEXP op, SEXP args, SEXP env);

第二个可能的解决方法是将源文件重命名为.c扩展名,并使用ac编译器进行编译,如果不是c ++代码,它将进行编译,并且您将不需要extern "C"

仅仅构造要在C级别进行评估的R调用,然后从那里去怎么样? 例如:

SEXP mySave(SEXP object, SEXP path) {
    SEXP call = PROTECT(Rf_lang3(Rf_install("saveRDS"), object, path);
    SEXP result = Rf_eval(call, R_GlobalEnv);
    UNPROTECT(1);
}

(根据需要用更合适的评估环境替换R_GlobalEnv

另一种可能性是使用R_Serialize()R_Unserialize() API,但它们似乎比实际的R级save API低得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM