Como posso descarregar um DLL usando ctypes em Python?
Pergunta
Eu estou usando ctypes para carregar uma DLL em Python. Isso funciona muito bem.
Agora nós gostaríamos de ser capaz de recarregar essa DLL em tempo de execução.
A abordagem simples parece ser: 1. Descarregue DLL 2. Coloque DLL
Infelizmente não tenho a certeza que a maneira correta para descarregar a DLL é.
_ctypes.FreeLibrary está disponível, mas privado.
Existe alguma outra maneira de descarregar o DLL?
Solução
Você deve ser capaz de fazê-lo pela eliminação do objeto
mydll = ctypes.CDLL('...')
del mydll
mydll = ctypes.CDLL('...')
EDIT: O comentário de Hop é certo, isso libera o nome, mas a coleta de lixo não acontece tão rapidamente, na verdade eu até duvido mesmo libera a biblioteca carregado.
Ctypes não parece fornecer uma maneira limpa para liberar recursos, ele não só fornecem um campo _handle
ao punho dlopen ...
Assim, a única maneira que eu vejo, realmente, realmente forma não limpa , é sistema dependente dlclose a alça, mas é muito, muito sujo, como ctypes além disso mantém referências internamente para esse identificador . Então descarga leva algo da forma:
mydll = ctypes.CDLL('./mylib.so')
handle = mydll._handle
del mydll
while isLoaded('./mylib.so'):
dlclose(handle)
É tão imunda que eu só verificada 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)
Outras dicas
É útil para ser capaz de descarregar a DLL para que você possa reconstruir a DLL sem ter que reiniciar a sessão se você estiver usando ipython ou fluxo de trabalho similar. Trabalhando em janelas Eu só tentaram trabalho com os Windows DLL métodos relacionados.
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)
Eu não sei muito dos internos, então eu realmente não estou certo como impecáveis ??este é. Eu acho que a exclusão de MyDll libera os recursos Python e a chamada FreeLibrary diz janelas para libertá-la. Eu tinha assumido que a liberação com FreeLibary primeiro teria produzido problemas assim que eu salvo uma cópia do identificador de biblioteca e libertou-o na ordem mostrada no exemplo.
I com base neste método em ctypes descarregamento dll que carregado o punho explicitamente na frente. A convenção de carregamento no entanto não funciona tão limpa quanto o simples "ctypes.cdll.LoadLibrary ( 'test.dll')" por isso optei para o método mostrado.
Se você precisar dessa funcionalidade, você poderia escrever 2 dlls onde as cargas dll_A / biblioteca descarrega da dll_B. Use dll_A como como python interface de carregador e de passagem para funções na dll_B.