Python ctypes и динамическое связывание - PullRequest
4 голосов
/ 09 апреля 2010

Я пишу некоторые библиотеки на C, которые содержат функции, которые я хочу вызывать из Python через ctypes.

Я успешно сделал это с другой библиотекой, но эта библиотека имела очень ванильные зависимости (а именно 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. Я пробовал разные вещи без какого-либо успеха, и я довольно застрял на этом этапе.

Ответы [ 2 ]

4 голосов
/ 09 апреля 2010

ОК, спасибо за вашу помощь.

, чтобы заставить это работать, я должен был включить зависимости при связывании (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

спасибо, -nick

0 голосов
/ 09 апреля 2010

Вам нужно связать libwaveprop.so с библиотекой fftw3. В противном случае Python просто не будет знать, куда идти, чтобы получить эти недостающие символы; чтение мыслей не реализовано ни на одном языке программирования.

...