Frage

Wie aktualisieren Sie diese Umgebungsvariable zur Laufzeit, so dass ctypes überall dort, wo eine Bibliothek laden kann? Ich habe folgendes versucht, und keiner scheint zu funktionieren.

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")
War es hilfreich?

Lösung

Durch die Zeit, ein Programm wie Python ausgeführt wird, der dynamische Lader (ld.so.1 oder etwas ähnliches) gelesen hat bereits LD_LIBRARY_PATH und werden alle Änderungen danach nicht bemerkt. Also, es sei denn, den Python Software selbst wertet LD_LIBRARY_PATH und nutzt sie den möglichen Pfadnamen der Bibliothek für dlopen() oder eine äquivalente Funktion zu bauen zu verwenden, die Variable im Skript Einstellung keine Auswirkung.

Da Sie sagen, dass es nicht funktioniert, scheint es plausibel anzunehmen, dass Python nicht funktioniert bauen und versuchen, alle möglichen Bibliotheksnamen; es beruht wahrscheinlich auf LD_LIBRARY_PATH allein.

Andere Tipps

Auch wenn Sie einen vollständigen Pfad zu CDLL oder cdll.LoadLibrary () geben, müssen Sie möglicherweise noch LD_LIBRARY_PATH setzen, bevor Python aufrufen. Wenn die gemeinsam genutzte Bibliothek, die Sie ausdrücklich auf eine andere gemeinsam genutzte Bibliothek bezieht sich laden und kein „rpath“ in der .so für diese Bibliothek gesetzt, dann wird es nicht gefunden werden, auch wenn es bereits geladen wurde. Ein rpath in einer Bibliothek gibt einen Suchpfad für andere Bibliotheken, die von dieser Bibliothek benötigt, um die Suche verwendet werden

Zum Beispiel habe ich einen Fall aus einer Reihe von voneinander abhängigen Bibliotheken von Drittanbietern nicht von mir produziert. b.so Referenzen a.so. Auch wenn ich im Voraus laden a.so:

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

Ich erhalte eine Fehlermeldung auf dem zweiten Last, weil b.so bezieht einfach ‚a.so‘, ohne rpath, und so b.so weiß nicht, das ist die richtige a.so. So habe ich LD_LIBRARY_PATH im Voraus auf '/ abs / path / to' aufzunehmen.

Um zu vermeiden, LD_LIBRARY_PATH zu setzen, können Sie den rpath Eintrag in den .so-Dateien ändern. Unter Linux gibt es zwei Dienstprogramme Ich fand, dass dies tun: chrpath und patchelf . chrpath ist aus dem Ubuntu-Repositories verfügbar. Es kann nicht rpath auf .so das ändern, die nie einen hatte. patchelf ist flexibler.

CDLL kann ein vollständig qualifizierten Pfadnamen übergeben werden, so zum Beispiel ich in eines meines Skripte folgend bin mit denen die .so im selben Verzeichnis wie der Python-Skript ist.

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

In Ihrem Fall sollten Folgendes genügen.

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

Stellen Sie sich Ihre binär mit einem rpath relativ zum aktuellen Arbeitsverzeichnis wie:

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

Dann sind Sie in der Lage das Arbeitsverzeichnis in Python zur Laufzeit ändern mit:

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

Wie dies auch der Lader findet andere dynamische Bibliotheken wie otherbinary.so

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top