[英]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.