2010-04-09 9 views
4

J'écris quelques bibliothèques en C qui contiennent des fonctions que je veux appeler depuis Python via des ctypes.Ctypes Python et liaison dynamique

Je l'ai fait avec succès une autre bibliothèque, mais cette bibliothèque ne comptait que des dépendances très vanille (à savoir fstream, math, malloc, stdio, stdlib). L'autre bibliothèque sur laquelle je travaille a des dépendances plus compliquées.

Par exemple, je vais essayer d'utiliser fftw3. En guise de test, je vais juste essayer de compiler un simple fichier contenant .cpp:

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

    printf("foo called.\n"); 

    return 0; 
}   

Je compilez comme:

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 

tout cela fonctionne. Maintenant, je le tester avec un autre fichier contenant .cpp:

int main() 
{ 
    foo(); 
} 

Résultat:

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

Ce qui est tout à fait raisonnable. Ensuite, j'essaie:

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

Super! Mais maintenant, quand je tente de charger la bibliothèque 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 

Il est donc le même problème, mais je ne sais pas comment le résoudre pour ctypes. J'ai essayé plusieurs choses sans succès, et je suis bloqué à ce point.

Répondre

0

Vous devez lier libwaveprop.so lui-même contre la bibliothèque fftw3. Sinon, Python ne saura simplement pas où aller pour obtenir ces symboles manquants; la lecture de l'esprit n'est implémentée dans aucun langage de programmation.

+0

Merci pour la réponse. C'est l'une des choses que j'ai essayées. ICPC -shared -Wl, -soname, libwaveprop.so.1 -o libwaveprop.so.1.0 libwaveprop.o -lfftw3 et ICPC -shared -Wl, -soname, libwaveprop.so.1 -o libwaveprop .so.1.0 libwaveprop.o les deux donnent la même erreur: ld: /usr/local/lib/libfftw3.a(malloc.o): ne peut pas être utilisé déplacement R_X86_64_PC32 vers le symbole fftw_kernel_malloc » lors d'un partagé objet; recompiler avec -fPIC ld: le lien final a échoué: Mauvaise valeur Je ne sais pas quoi faire avec ça. Des idées? merci, -nick –

+0

Bien, "compiler à' .o' avec '-fPIC' et lier à'.donc contre les bibliothèques dont vous dépendez "est la technique que j'ai apprise. Impossible de diagnostiquer ce qui ne va pas sans plus d'informations, désolé. –

4

OK, merci pour votre aide.

Pour que cela fonctionne, j'ai dû inclure les dépendances lors de la liaison (duh). J'avais essayé ceci avant mais ai eu une erreur, ainsi résolus ceci j'ai dû recompiler fftw avec '-fpic' comme drapeau de CPP. tout fonctionne maintenant.

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 

grâce, -Nick