2012-02-15 55 views
6

我想複製Flavian Coelho,linked here的工作。他使用Cython和Gnu科學圖書館(GSL)在Python中產生隨機數,從而大大加快了速度。當我輸入在Python我編譯用Cython代碼(用命令import cgibbs),我收到以下錯誤:連接外部C庫時從Cython導入錯誤

ImportError: dlopen(./cgibbs.so, 2): Symbol not found: _gsl_rng_mt19937 
    Referenced from: /Users/wesley/scratch/cython/cgibbs.so 
    Expected in: dynamic lookup 

你會發現,抱怨是符號_gsl_rng_mt19937無法找到。我試圖鏈接到的函數被稱爲gsl_rng_mt19937(無前導下劃線),這就是它在我的.pyx文件中的顯示方式。我認爲Cython通過添加領先的下劃線以某種方式導致問題。

爲了使故障排除更容易,我已將代碼剝離下來併發布到下面。我的系統是:運行Python 2.7.2(32位)的Mac OSX 10.7(Lion),gcc-4.0(我用它編譯32位格式的GSL庫),GSL 1.15和Cython v0.15.1。

這裏是cgibbs.pyx的內容:

#declaring external GSL functions to be used 
cdef extern from "math.h": 
    double sqrt(double) 

cdef double Sqrt(double n): 
    return sqrt(n) 

cdef extern from "gsl/gsl_rng.h": 
    ctypedef struct gsl_rng_type: 
     pass 
    ctypedef struct gsl_rng: 
     pass 
    gsl_rng_type *gsl_rng_mt19937 
    gsl_rng *gsl_rng_alloc(gsl_rng_type * T) 

cdef extern from "gsl/gsl_randist.h": 
    double gamma "gsl_ran_gamma"(gsl_rng * r,double,double) 
    double gaussian "gsl_ran_gaussian"(gsl_rng * r,double) 


cdef gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937) 

錯誤消失,如果我註釋掉我cgibbs.pyx的最後一行,但我不能實際使用的外部庫...任何您可以提供的洞察力表示讚賞。謝謝!

回答

4

感謝@ChuiTey,我發現otoolnm是Mac上的工具,可以執行objdump在Linux上的工作。用nm我發現前導下劃線是libgsl.a庫中符號名稱的一部分。

一旦我知道鏈接器(在我的情況下,ld)正在尋找正確的名稱,很明顯它只是沒有找到正確的位置。這就是我得知頭文件不知道它們鏈接到的庫的位置(Duh!)我只需要將選項-lgsl添加到運行鏈接器的命令(這需要libgsl.a位於目錄中你的鏈接查找圖書館 - 我的機器上,這是/usr/local/lib

我也有過,因爲它被編譯爲一個64位平臺,我使用32位的Python從/usr/local/lib移動libgsl.dylib

在使用distutils或makefile編譯Cython代碼時,必須有一種簡單的方法來指定-lgsl鏈接器選項;現在我只需運行gcc-4.0兩次來編譯並鏈接模塊。我的工作流程來編譯從bash命令線用Cython模塊是:

cython cgibbs.pyx 
gcc-4.0 -m32 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c cgibbs.c -o cgibbs.o 
gcc-4.0 -bundle -undefined dynamic_lookup -lgsl -arch i386 -g cgibbs.o -o cgibbs.so 

哪個產生cgibbs.so,可以在Python 2.7被導入一個用Cython模塊。

2

將下劃線前置到導出的函數稱爲name mangling。在Windows上,cdecl約定附加一個下劃線(其他約定具有更復雜的方案)。

這可能是您在構建GSL庫時沒有正確指定調用約定。您應該能夠看看使用objdump導出的名稱。

GSL是否已經提供SWIG包裝?

+0

我不知道從SWIG--也許我應該這樣做。 – Wesley 2012-02-16 02:44:48