6

ここにリンクされている、Flavian Coelho の作品を複製しようとしています。彼は Cython と Gnu Scientific Library (GSL) を使用して、乱数の生成を Python より大幅に高速化しました。コンパイルした Cython コードを Python で (コマンドを使用してimport cgibbs) インポートすると、次のエラーが発生します。

  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 (GSL ライブラリを 32 ビット形式でコンパイルするために使用)、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

3 に答える 3

4

@ChuiTey のおかげで、Linux で objdump が行うことを実行できる Mac 上のツールであることotoolを発見しました。先頭のアンダースコアがライブラリのシンボル名の一部であるnmことがわかりました。nmlibgsl.a

リンカ (私の場合はld) が正しい名前を探していることがわかったら、正しい場所を探していないことは明らかでした。そして、それがヘッダーファイルがリンク先のライブラリの場所を知らないことを学んだ方法です(Duh!)-lgslリンカーを実行するコマンドにオプションを追加する必要がlibgsl.aありました(これには、リンカーが存在するディレクトリにある必要がありますライブラリを探します - 私のマシンでは、それは/usr/local/lib.)

また、64 ビット プラットフォーム用にコンパイルされており、32 ビット Python を使用しているため、移行する必要libgsl.dylibがありました。/usr/local/lib

-lgsldistutils または makefile を使用して Cython コードをコンパイルするときに、リンカー オプションを指定する簡単な方法が必要です。今のところ、モジュールをコンパイルしてからリンクするために、gcc-4.0 を 2 回実行しています。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 モジュールが生成されます。

于 2012-02-16T02:44:18.257 に答える
2

エクスポートされた関数の先頭にアンダースコアを追加することは、名前マングリングと呼ばれます。Windows では、cdecl 規則により 1 つのアンダースコアが追加されます (他の規則にはより複雑なスキームがあります)。

GSL ライブラリをビルドするときに、呼び出し規約を正しく指定していない可能性があります。objdumpを使用してエクスポートされる名前を確認できるはずです。

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

于 2012-02-16T00:01:55.073 に答える
0

Cython で GSL 関数を使いたい場合は、CythonGSL ( https://github.com/twiecki/CythonGSL ) を参照してください。

于 2013-03-27T19:55:47.250 に答える