Python ctypes and dynamic linking

前提是你 提交于 2019-12-10 17:50:54

问题


I'm writing some libraries in C which contain functions that I want to call from Python via ctypes.

I've done this successfully another library, but that library had only very vanilla dependencies (namely fstream, math, malloc, stdio, stdlib). The other library I'm working on has more complicated dependencies.

For example, I'll try to use fftw3. As a test, I'll just try to compile a simple .cpp file containing:

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

    printf("foo called.\n");

    return 0;
}        

I compile it as:

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

This all works. Now I test it with another .cpp file containing:

int main()
{
    foo();
}

Result:

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

Which is entirely reasonable. Next I try:

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

Great! But now when I try to load the library with 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

So it's the same problem, but I have no idea how to resolve it for ctypes. I've tried various things without any success, and I'm pretty stuck at this point.


回答1:


OK, thanks for your help.

to get this to work I had to include the dependencies when linking (duh). I had tried this before but got an error, so solve this I had to recompile fftw with '-fpic' as a CPP flag. all works now.

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

thanks, -nick




回答2:


You need to link libwaveprop.so itself against the fftw3 library. Otherwise Python simply won't know where to go to get those missing symbols; mind-reading isn't implemented in any programming language.



来源:https://stackoverflow.com/questions/2606450/python-ctypes-and-dynamic-linking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!