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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top