Pregunta

Estoy usando ctypes para cargar un archivo DLL en Python. Esto funciona muy bien.

Ahora nos gustaría ser capaz de recargar esa DLL en tiempo de ejecución.

El enfoque directo parecería ser: 1. Descargar DLL 2. Cargar DLL

Por desgracia, no estoy seguro de lo que la forma correcta para descargar el archivo DLL es.

_ctypes.FreeLibrary está disponible, pero privado.

¿Hay alguna otra forma de descargar el archivo DLL?

¿Fue útil?

Solución

que debe ser capaz de hacerlo disponiendo el objeto

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

EDIT: Comentario del lúpulo es correcto, esto desata el nombre, pero la recolección de basura no sucede tan rápido, de hecho, incluso lo dudo incluso libera la biblioteca cargado.

ctypes no parece proporcionar una forma limpia para liberar recursos, no sólo proporcionan un campo _handle al mango dlopen ...

Así que la única forma en que veo, realmente, realmente de forma no limpia , es el sistema de forma dependiente dlclose el mango, pero es muy muy sucio, como ctypes Por otra parte mantiene internamente referencias a este mango . Por lo tanto la descarga toma algo de la forma:

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

Es tan sucio que yo sólo comprobado que funciona usando:

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)

Otros consejos

Es útil para poder descargar el archivo DLL para que pueda reconstruir el archivo DLL sin tener que reiniciar la sesión si está utilizando IPython o flujo de trabajo similar. Trabajando en las ventanas sólo he intentado trabajar con los métodos relacionados ventanas DLL.

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)

No sé mucho de las partes internas así que no estoy realmente seguro de lo limpio que es esto. Creo que la supresión de mydll libera los recursos de Python y la llamada FreeLibrary dice ventanas para liberarla. Yo había asumido que la liberación con FreeLibary primero habría producido problemas así que guardado una copia de la empuñadura de la biblioteca y se libera en el orden que se muestra en el ejemplo.

I basa este método en descargan DLL que carga el mango de forma explícita en la delantera. La convención de carga sin embargo no funciona tan limpiamente como la simple "ctypes.cdll.LoadLibrary ( 'test.dll')" así que optamos por el método mostrado.

Si necesita esta funcionalidad, se podría escribir 2 dlls donde las cargas dll_A / biblioteca se descarga del dll_B. Utilizar como dll_A como Python interfaz de cargador y de paso a través de las funciones en dll_B.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top