【问题标题】:Python ctypes and dynamic linkingPython ctypes 和动态链接
【发布时间】:2010-04-09 09:56:15
【问题描述】:

我正在用 C 编写一些库,其中包含我想通过 ctypes 从 Python 调用的函数。

我已经成功地完成了另一个库,但该库只有非常普通的依赖项(即fstreammathmallocstdiostdlib)。我正在研究的另一个库具有更复杂的依赖关系。

例如,我将尝试使用fftw3。作为测试,我将尝试编译一个简单的.cpp 文件,其中包含:

int foo()
{
    void *p  = fftw_malloc( sizeof(fftw_complex)*64 );
    fftw_free(p);

    printf("foo called.\n");

    return 0;
}        

我编译为:

icpc -Wall -fPIC -c waveprop.cpp -o libwaveprop.o $std_link
icpc -shared -Wl,-soname,libwaveprop.so.1 -o libwaveprop.so.1.0 libwaveprop.o 

cp waveprop.so.1.0 /usr/local/lib/
rm waveprop.so.1.0
ln -sf /usr/local/lib/waveprop.so.1.0 /usr/local/lib/waveprop.so
ln -sf /usr/local/lib/waveprop.so.1.0 /usr/local/lib/waveprop.so.1

这一切都有效。现在我用另一个包含以下内容的.cpp 文件对其进行测试:

int main()
{
    foo();
}

结果:

icpc test.cpp -lwaveprop 
/lib/../lib64/libwaveprop.so: undefined reference to `fftw_free'
/lib/../lib64/libwaveprop.so: undefined reference to `fftw_malloc'

这是完全合理的。接下来我试试:

icpc test.cpp -lwaveprop -lfftw3
./a.out
foo called.

太棒了!但是现在当我尝试使用 ctypes 加载库时:

>>> from ctypes import *
>>> print cdll.LoadLibrary('/usr/local/lib/libwaveprop.so.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/ctypes/__init__.py", line 431, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib64/python2.6/ctypes/__init__.py", line 353, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /usr/local/lib/libwaveprop.so.1: undefined symbol: fftw_free

所以这是同样的问题,但我不知道如何为 ctypes 解决它。我已经尝试了各种方法,但都没有成功,现在我陷入了困境。

【问题讨论】:

    标签: python ctypes dynamic-linking


    【解决方案1】:

    好的,谢谢你的帮助。

    为了让它工作,我必须在链接时包含依赖项(duh)。我之前尝试过,但遇到了错误,所以解决这个问题我必须重新编译 fftw 并使用 '-fpic' 作为 CPP 标志。现在一切正常。

    icpc -Wall -fPIC -c waveprop.cpp -o libwaveprop.o $std_link
    icpc -shared -Wl,-soname,libwaveprop.so.1 -o libwaveprop.so.1.0 libwaveprop.o -lfftw3
    
    cp waveprop.so.1.0 /usr/local/lib/
    rm waveprop.so.1.0
    ln -sf /usr/local/lib/waveprop.so.1.0 /usr/local/lib/waveprop.so
    ln -sf /usr/local/lib/waveprop.so.1.0 /usr/local/lib/waveprop.so.1
    

    谢谢, -尼克

    【讨论】:

      【解决方案2】:

      您需要将libwaveprop.so 本身链接到 fftw3 库。否则 Python 根本不知道去哪里获取那些丢失的符号;读心术没有用任何编程语言实现。

      【讨论】:

      • 感谢您的回复。这是我尝试过的事情之一。 icpc -shared -Wl,-soname,libwaveprop.so.1 -o libwaveprop.so.1.0 libwaveprop.o -lfftw3 和 icpc -shared -Wl,-soname,libwaveprop.so.1 -o libwaveprop.so.1.0 libwaveprop。 o 两者都给出相同的错误: ld: /usr/local/lib/libfftw3.a(malloc.o): relocation R_X86_64_PC32 against symbol `fftw_kernel_malloc' can not be used when making a shared object;使用 -fPIC ld 重新编译:最终链接失败:错误值我不知道该怎么办。有任何想法吗?谢谢,-尼克
      • 嗯,“用-fPIC 编译到.o 并针对您所依赖的库链接到.so”是我学到的技术。没有更多信息,无法诊断出问题所在,抱歉。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-26
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 2012-05-14
      相关资源
      最近更新 更多