我使用ctypes在Python中加載DLL。這很好。如何在Python中使用ctypes卸載DLL?
現在我們希望能夠在運行時重新加載該DLL。
的簡單的方法似乎是:1。 卸載DLL 2.加載DLL
不幸的是我不知道什麼是正確的方法卸載DLL是。
_ctypes.FreeLibrary可用,但私有。
有沒有其他的方式來卸載DLL?
我使用ctypes在Python中加載DLL。這很好。如何在Python中使用ctypes卸載DLL?
現在我們希望能夠在運行時重新加載該DLL。
的簡單的方法似乎是:1。 卸載DLL 2.加載DLL
不幸的是我不知道什麼是正確的方法卸載DLL是。
_ctypes.FreeLibrary可用,但私有。
有沒有其他的方式來卸載DLL?
你應該能夠做到這一點通過設置對象
mydll = ctypes.CDLL('...')
del mydll
mydll = ctypes.CDLL('...')
編輯:合的評論是正確的,這解除綁定的名稱,但是垃圾收集不會發生很快,其實我連懷疑它甚至會釋放加載的庫。
ctypes的似乎沒有提供一個乾淨的方式來釋放資源,但它僅在dlopen的手柄提供了_handle
場...
所以我看到的唯一途徑,真的,真的非乾淨的方式,是依賴系統dlclose句柄,但它是非常非常不潔的,因爲此外ctypes內部引用此句柄。所以卸載採取的形式的東西:
mydll = ctypes.CDLL('./mylib.so')
handle = mydll._handle
del mydll
while isLoaded('./mylib.so'):
dlclose(handle)
它是如此污穢,我只檢查了它的工作原理使用:
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)
這是非常有意義的,能夠卸載DLL,這樣就可以重建DLL而無需在使用iPython或類似工作流時重新啓動會話。在Windows中工作我只嘗試使用與Windows 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)
我不太瞭解內部,所以我不確定這是多麼的乾淨。我認爲刪除mydll可以釋放Python資源,FreeLibrary調用會告訴windows釋放它。我曾經假定,首先釋放FreeLibary會產生問題,所以我保存了庫處理的副本,並按照示例中所示的順序釋放它。
我基於ctypes unload dll這個方法,它明確地加載了句柄。然而,加載約定不像簡單的「ctypes.cdll.LoadLibrary('test.dll')」那樣乾淨,所以我選擇了所示的方法。
你有沒有找到更好的答案,我的醜陋的方式?如果不是,你應該問他們的郵件列表,如果它不存在錯誤報告它。 'del'應該調用函數來釋放資源! – 2009-01-22 15:00:19