2013-04-18 71 views
0

我在C中編寫gibbs函數,並希望使用隨機數函數,如rnorm()。架構x86_64的未定義符號:getRNGstate()和putRNGstate()

我的代碼是這樣的:

#include <stdio.h> 
#include <string.h> 
#include <R.h> 
#include <Rmath.h> 
void foo(int *nin, double *x) 
{ 
    int n = nin[0]; 

    int i; 
    GetRNGstate(); 

    for (i=0; i<n; i++) 
    { 
     x[i] = rchisq(2); 
     Rprintf("%f\n",x[i]); 
    } 
    // exit R random-gen routine 
    PutRNGstate(); 
} 

然而,當我試圖在Xcode打造,該錯誤信息是:

> Undefined symbols for architecture x86_64: "_GetRNGstate", 
> referenced from: 
>  _gibbs in main.o "_PutRNGstate", referenced from: 
>  _gibbs in main.o "_Rf_rchisq", referenced from: 
>  _gibbs in main.o "_Rf_rnorm", referenced from: 
>  _gibbs in main.o "_Rf_runif", referenced from: 
>  _gibbs in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see 
> invocation) 

我使用Xcode和我知道,我都R和R64bit。在終端$ R運行R64bit和我的Aquamacs也運行R64bit。我不知道它是否是不同版本的碰撞,如果是這樣,我如何說服Xcode正確地引用R?

順便說一句我發現R.h和rmath.h文件至少有3個地方!我不知道我應該在Xcode中重新定位哪條路徑! 目前我正在添加與第三個相同的標題路徑。所有#include都可以正常工作。

R.Frameworks/Headers 
R.Frameworks/Versions/2.15/Resources/include 
R.Frameworks/Versions/Current/Resources/include 

但無論哪種方式,沒有得到任何RNORM C函數() - 像功能會有效和R可以通過dyn.load使用它()。

所以請幫助!

非常感謝!

+0

那麼,我用終端編譯,比如R CMD SHLIB main.c,然後使用dyn.load()blar blar ...它的工作原理! wtf ...爲什麼Xcode無法弄清楚那些getRNGstate()? – Lisa

+0

當您調用R CMD SHLIB時,請密切關注完整的gcc行 - 因爲R知道要鏈接的內容,它可以工作。我擔心你對Xcode的調用不完整。 –

+0

謝謝Dirk,當我處理Xcode時,我只點擊Build按鈕,所以我實際上不知道Xcode調用哪個編譯器。我可以在R CMD中說SHLIB main.c實際上R是編譯器嗎? – Lisa

回答

0

僅分析編譯器輸出,它無法找到實現這些函數的代碼段。通常它們是在庫中實現的,也許你沒有向它傳遞你的代碼必須鏈接到的一組庫。

我想說的是,你必須編譯或驗證您的腳本編譯你的代碼類似的東西(假設你正在使用gcc編譯):

的gcc -o程序main.o -llibrary1 -llibrary2 ...

其中這些庫來自於你的框架(只是要記住,如果你的庫稱爲libxxx.so你必須通過與gcc -lxxx)

+0

感謝您的回覆!我認爲圖書館的路徑很好。因爲我添加了R /.../include到路徑中,至少Rprintf()工作。這只是getRNGstate()putRNGstata()保持失敗..我不知道爲什麼。順便說一句,如果我在終端中使用R CMD SHLIB它再次工作..這是一個Xcode的問題? – Lisa

1

你的問題是不完整和不重複性缺乏實際的代碼。有幾個問題,我可以建議:

  1. 有與R.前導下劃線所有你無法鏈接常規使用的符號,符號PutRNGstate()Rf_rchisq(),...也許你只需要一個修復切換你意外設置?

  2. 從您的文章中不清楚您是否想要將某些內容作爲動態擴展加載到R中,或者是否要使用這些R函數編寫獨立程序。你可以做到這一點。

  3. 調用一個自寫函數可能是微不足道的。通過學習Rcpp,我們甚至可以做 cppFunction('double foo(int df) { return Rf_rchisq(df); }')並重復呼叫foo(3) (因爲Rcpp通過它的RNGScope類爲我們處理RNG狀態)。

  4. 如果您想單獨使用某些東西,請查看Writing R Extensions手冊和Rmathlib庫。我之前已經發布了一些小例子。

+0

非常感謝您的回覆。我剛剛編輯我的帖子以顯示原始代碼。我這樣做的動機是,在R中我必須編寫一些for循環並且不能使用apply(),所以我想將該部分移到C中以加快速度。但是在循環內部,我已經使用了一系列R函數(比如說,RNG,apply()等),所以我必須確保RNG的工作。實際上,後來也許我會看看apply()是否適用於C.否則,我可能不得不將所有apply()再次轉換爲for循環... – Lisa

+0

我對cppFunction()不熟悉。這是否意味着在c/cpp中,您可以擺脫RNGstate()函數,但只需編寫rchisq()?然後在R中的cppFunction中調用它呢? – Lisa

+0

總之,是的。 'rchisq()'甚至是矢量化的,所以你可以在一次調用中得到'N'。但請閱讀Rcpp文檔 - 並參閱示例,例如http://gallery.rcpp.org –

相關問題