问题
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