簡體   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