Frage

Ich verwende ctypes eine DLL in Python zu laden. Dies funktioniert gut.

Nun möchten wir in der Lage sein mag, dass DLL zur Laufzeit zu laden.

Der einfachste Ansatz scheint zu sein: 1. Unload DLL 2. Legen Sie DLL

Leider bin ich nicht sicher, was der richtige Weg, um die DLL zu entladen ist.

_ctypes.FreeLibrary ist verfügbar, aber privat.

Gibt es eine andere Möglichkeit, um die DLL zu entladen?

War es hilfreich?

Lösung

Sie sollten es tun können, indem Sie das Objekt Entsorgung

mydll = ctypes.CDLL('...')
del mydll
mydll = ctypes.CDLL('...')

EDIT: Hop Kommentar ist richtig, das den Namen entbindet, aber die Garbage Collection nicht geschieht so schnell, ich selbst in der Tat bezweifeln sogar die geladene Bibliothek freigibt.

Ctypes scheint nicht eine saubere Art und Weise zu schaffen, Ressourcen freizugeben, ist es nur ein _handle Feld zum dlopen Griff bereitstellt ...

So ist die einzige Art, wie ich sehe, eine wirklich, wirklich nicht saubere Art und Weise , ist abhängig von System des Griff dlclose, aber es ist sehr, sehr unsauber, wie im übrigen ctypes intern Referenzen hält an diesen Griff . So Entladen nimmt etwas von der Form:

mydll = ctypes.CDLL('./mylib.so')
handle = mydll._handle
del mydll
while isLoaded('./mylib.so'):
    dlclose(handle)

Es ist so unrein, dass ich nur überprüft, es funktioniert mit:

def isLoaded(lib):
   libp = os.path.abspath(lib)
   ret = os.system("lsof -p %d | grep %s > /dev/null" % (os.getpid(), libp))
   return (ret == 0)

def dlclose(handle)
   libdl = ctypes.CDLL("libdl.so")
   libdl.dlclose(handle)

Andere Tipps

Es ist hilfreich, wenn die DLL zu entladen, so dass Sie die DLL wieder aufbauen können, ohne dass die Sitzung neu zu starten, wenn Sie ipython oder ähnlichen Arbeitsablauf verwenden. Arbeiten in den Fenstern habe ich versucht, nur mit den Windows-DLL verwandten Methoden zu arbeiten.

REBUILD = True
if REBUILD:
  from subprocess import call
  call('g++ -c -DBUILDING_EXAMPLE_DLL test.cpp')
  call('g++ -shared -o test.dll test.o -Wl,--out-implib,test.a')

import ctypes
import numpy

# Simplest way to load the DLL
mydll = ctypes.cdll.LoadLibrary('test.dll')

# Call a function in the DLL
print mydll.test(10)

# Unload the DLL so that it can be rebuilt
libHandle = mydll._handle
del mydll
ctypes.windll.kernel32.FreeLibrary(libHandle)

Ich weiß nicht viel über die Interna so bin ich nicht wirklich sicher, wie sauber das ist. Ich denke, dass mydll Löschen gibt die Python-Ressourcen und der Free Anruf erzählt Fenster, die es zu befreien. Ich hatte angenommen, dass zuerst mit FreeLibary befreien würde Probleme erzeugt, damit ich eine Kopie der Bibliothek Griff und befreite sie in der Reihenfolge, in dem gezeigten Beispiel gespeichert.

basierend ich diese Methode auf ctypes dll entladen, die den Griff ausdrücklich vorne geladen. Die Lade Konvention jedoch nicht so sauber funktioniert wie das einfache „ctypes.cdll.LoadLibrary (‚test.dll‘)“, so entschied ich mich für das Verfahren gezeigt.

Wenn Sie diese Funktion benötigen, könnten Sie schreiben 2 dlls wo dll_A Lasten / leert Bibliothek von dll_B. Verwenden Sie dll_A wie Python-Schnittstelle-Loader und Pass-Through für Funktionen in dll_B.

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