2012-02-15 10 views
6

Flavian Coelhoの作品を複製しようとしています。linked here CythonとGnu Scientific Library(GSL)を使用して、Pythonに比べて乱数を生成する速度が大幅に向上しました。私は(コマンドimport cgibbs付き)Pythonで私のコンパイルCythonコードをインポートすると、私は次のエラーを取得する:外部CライブラリをリンクするときにCythonからImportErrorをインポートする

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ビット版)、gcc-4.0(GSLライブラリを32ビット形式でコンパイルしたもの)、GSL 1.15、Cython v0.15.1を実行するMac OSX 10.7(Lion)です。ここで

は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が、Linux上でobjdumpの機能を果たすことができるMac上のツールであることを発見しました。 nmでは、先頭のアンダースコアがlibgsl.aライブラリのシンボル名の一部であることがわかりました。

リンカー(私の場合はld)が正しい名前を探していることが分かったら、正しい場所を探していないことが明らかでした。そして、それは私がヘッダーファイルがリンカー(Duh!)のライブラリの場所を知らないことを知った方法です。あなたのリンカがライブラリを検索します - 。私のマシン上で、それは/usr/local/libです)

私もそれが64ビットプラットフォーム用にコンパイルされたと私は、32ビットのPythonを使用していますので、/usr/local/libからlibgsl.dylibを移動しなければなりませんでした。

distutilsまたはmakefileを使用してCythonコードをコンパイルするときに、-lgslリンカオプションを指定する簡単な方法が必要です。今はモジュールをコンパイルしてリンクするためにgcc-4.0を2回実行しています。 bashコマンドラインからCythonモジュールをコンパイルする私のワークフローは次のとおりです。

cgibbs.so、Pythonの2.7にインポートすることができ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 

2

エクスポートされた関数にアンダースコアを付加することは、name manglingと呼ばれます。 Windowsでは、cdecl規則は単一のアンダースコアを追加します(他の規則ではより複雑なスキームがあります)。

GSLライブラリを構築するときに、呼び出し規約を正しく指定していない可能性があります。 objdumpを使用して、エクスポートする名前を調べることができます。

GSLはすでにSWIGラッパーを提供していませんか?

+0

私はSWIGからは分かりません。 – Wesley

関連する問題