Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 链接外部C库时从Cython导入错误_Python_C_Cython_Gsl - Fatal编程技术网

Python 链接外部C库时从Cython导入错误

Python 链接外部C库时从Cython导入错误,python,c,cython,gsl,Python,C,Cython,Gsl,我试图复制弗拉维安·科埃略的作品。他使用Cython和Gnu科学库(GSL)在生成随机数方面比Python有了巨大的速度。当我在Python中导入已编译的Cython代码时(使用命令import cgibbs),我得到以下错误: ImportError: dlopen(./cgibbs.so, 2): Symbol not found: _gsl_rng_mt19937 Referenced from: /Users/wesley/scratch/cython/cgibbs.so E

我试图复制弗拉维安·科埃略的作品。他使用Cython和Gnu科学库(GSL)在生成随机数方面比Python有了巨大的速度。当我在Python中导入已编译的Cython代码时(使用命令
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
您会注意到投诉是找不到符号
\u gsl\u rng\u mt19937
。我试图链接到的函数名为
gsl\u rng\u mt19937
(无前导下划线),这就是它在我的
.pyx
文件中的显示方式。我认为Cython添加了那条主要的下划线,不知何故造成了这个问题

为了使故障排除更容易,我将代码剥离并发布在下面。我的系统是:MacOSX10.7(Lion),运行Python 2.7.2(32位)、gcc-4.0(我用它以32位的形式编译GSL库)、GSL1.15和CythonV0.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
的最后一行,错误就会消失,但是我实际上无法使用外部库。。。感谢您提供的任何见解。谢谢

在导出函数前加下划线称为。在Windows上,cdecl约定附加一个下划线(其他约定有更复杂的方案)

可能是您在构建GSL库时没有正确指定调用约定。您应该能够查看使用导出的名称


GSL不是已经提供SWIG包装了吗?

多亏了@ChuiTey,我发现Mac上的
otool
nm
工具可以完成objdump在Linux上的功能。在
nm
中,我发现前导下划线是
libgsl.a
库中符号名称的一部分

一旦我知道链接器(在我的例子中,
ld
)正在寻找正确的名称,很明显它找不到正确的位置。这就是为什么我知道头文件不知道它们链接到的库的位置(Duh!)我只需要在运行链接器的命令中添加选项
-lgsl
(这要求
libgsl.a
位于链接器查找库的目录中-在我的机器上,即
/usr/local/lib

我还必须从
/usr/local/lib
中移动
libgsl.dylib
,因为它是为64位平台编译的,我使用的是32位Python

在使用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模块。

当你想在Cython中使用GSL函数时,请看一下CythonGSL()。

我不知道来自SWIG-也许我应该这样做。