Question

Comment mettre à jour cette variable d'environnement lors de l'exécution afin que ctypes peut charger une bibliothèque où? Je l'ai essayé ce qui suit et ne semble fonctionner.

from ctypes import *
os.environ['LD_LIBRARY_PATH'] = "/home/starlon/Projects/pyCFA635/lib"  
os.putenv('LD_LIBRARY_PATH', "/home/starlon/Projects/pyCFA635/lib")  
lib = CDLL("libevaluator.so")
Était-ce utile?

La solution

Au moment où un programme tel que Python est en cours d'exécution, le chargeur dynamique (ld.so.1 ou quelque chose de similaire) a déjà lu LD_LIBRARY_PATH et ne remarqueront aucun changement par la suite. Donc, à moins que le logiciel lui-même Python et utilise LD_LIBRARY_PATH évalue pour construire le chemin possible de la bibliothèque ou une fonction dlopen() équivalente à utiliser, configurer la variable dans le script n'a aucun effet.

Étant donné que vous dites cela ne fonctionne pas, il semble plausible de supposer que Python ne construit pas et essayer tous les noms de bibliothèque possibles; elle repose probablement sur LD_LIBRARY_PATH seul.

Autres conseils

Même si vous donnez un chemin complet CDLL ou cdll.LoadLibrary (), vous pouvez toujours besoin de mettre LD_LIBRARY_PATH avant d'appeler Python. Si la bibliothèque partagée que vous chargez fait explicitement référence à une autre bibliothèque partagée et non « rpath » est situé dans le .donc pour cette bibliothèque, il ne sera pas trouvée, même si elle a déjà été chargé. Un rpath dans une bibliothèque spécifie un chemin de recherche à utiliser pour rechercher d'autres bibliothèques nécessaires par cette bibliothèque

Par exemple, je le cas d'un ensemble de bibliothèques tierces interdépendantes ne sont pas produites par moi. b.so références a.so. Même si je charge a.so à l'avance:

ctypes.cdll.LoadLibrary('/abs/path/to/a.so')
ctypes.cdll.LoadLibrary('/abs/path/to/b.so')

Je reçois une erreur sur la deuxième charge, car b.so se réfère simplement « a.so », sans rpath, et ainsi b.so ne sait pas que ce soit le bon a.so. Je dois donc mettre LD_LIBRARY_PATH à l'avance pour inclure '/ abs / chemin / vers.

Pour éviter d'avoir à mettre LD_LIBRARY_PATH, vous modifiez l'entrée rpath dans les fichiers .so. Sous Linux, il y a deux utilitaires je trouve que faire ceci: chrpath, et patchelf . chrpath est disponible dans les dépôts Ubuntu. Il ne peut pas changer rpath sur des années .so qui n'a jamais eu un. patchelf est plus souple.

CDLL peut être passé un nom de chemin complet, donc par exemple que je utilise ce qui suit dans l'un de mes scripts où le .donc est dans le même répertoire que le script python.

import os
path = os.path.dirname(os.path.realpath(__file__))
dll = CDLL("%s/iface.so"%path)

Dans votre cas, ce qui suit devrait suffire.

from ctypes import *
lib = CDLL("/home/starlon/Projects/pyCFA635/lib/libevaluator.so")

Compiler votre binaire avec un rpath par rapport au répertoire de travail courant comme:

gcc -shared -o yourbinary.so yoursource.c otherbinary.so \
    -Wl,-rpath='.',-rpath='./another/relative/rpath' -fpic

Ensuite, vous êtes en mesure de changer le répertoire de travail en python à l'exécution avec:

import os
os.chdir('/path/to/your/binaries')

Comme cela, le chargeur trouve également d'autres bibliothèques dynamiques comme otherbinary.so

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top