4

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

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

例如,我将尝试使用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 解决它。我已经尝试了各种事情但没有成功,我现在很困惑。

4

2 回答 2

4

好的,谢谢你的帮助。

为了让它工作,我必须在链接时包含依赖项(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

谢谢,-尼克

于 2010-04-09T11:54:00.190 回答
0

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

于 2010-04-09T10:02:36.697 回答