[英]How to save R object from C API
I need to save a R expression to a file, essentially 我基本上需要将R表达式保存到文件中
save( x, file="myfile.Rdata")
however, I need to do it from C/C++ API (since the value of 'x' is evaluated by a C++ function, that's loaded as a plugin to R). 但是,我需要从C / C ++ API中执行此操作(因为“ x”的值是由C ++函数求值的,因此将其作为R的插件加载)。 After researching the question on the net, and not finding anything useful, I went digging to the code, and figured out that there is a function "do_save" in src/main/saveload.c
在网上研究了问题之后,没有找到任何有用的东西,我去研究了一下代码,发现src / main / saveload.c中有一个函数“ do_save”。
SEXP attribute_hidden do_save(SEXP call, SEXP op, SEXP args, SEXP env)
that's the .Internal that does all the work when I type "save" in R, but apparently I can't link the resulting plugin properly against R, I get the error message: 那是.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_
Generally speaking, how is one supposed to use these internal functions in C API, or in other words, how is one supposed to evaluate a build-in R function from the C API? 一般来说,应该如何在C API中使用这些内部函数,换句话说,应该如何从C API中评估内置R函数?
When you write a c++ function, the function name in the binary file gets changed or " mangled " to allow function overloading to work. 当你写一个C ++函数,在二进制文件中的函数名被更改或“ 错位 ”,允许函数重载工作。 To avoid that, you can use
extern "C"
, if you are not really using any c++ specific syntax or feature then use ac compiler. 为避免这种情况,可以使用
extern "C"
,如果您实际上并没有使用任何c ++特定的语法或功能,请使用ac编译器。
For the first fix, it would go like this, 对于第一个修复,它会像这样,
extern "C" SEXP attribute_hidden do_save(SEXP call, SEXP op, SEXP args, SEXP env);
The second possible fix, is to rename your source file to have the .c extensions and compile with ac compiler, if it's not c++ code it will compile and you will not need extern "C"
. 第二个可能的解决方法是将源文件重命名为.c扩展名,并使用ac编译器进行编译,如果不是c ++代码,它将进行编译,并且您将不需要
extern "C"
。
What about just constructing the R call to be evaluated at the C level, and going from there? 仅仅构造要在C级别进行评估的R调用,然后从那里去怎么样? Eg something like:
例如:
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);
}
(replace R_GlobalEnv
with a more appropriate evaluation environment as needed) (根据需要用更合适的评估环境替换
R_GlobalEnv
)
The other possibility is using the R_Serialize()
and R_Unserialize()
APIs, but those seem somewhat more low-level than the actual R-level save
APIs. 另一种可能性是使用
R_Serialize()
和R_Unserialize()
API,但它们似乎比实际的R级save
API低得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.