2013-03-21 57 views
4

我在各種Python代碼鹼來動態地生成所看到的一個常見的成語/加載一個C函數在運行時是:載入臨時的DLL成Python在Win32

import tempfile 
import shutil 
from ctypes import CDLL 

workdir = tempfile.mkdtemp() 
try: 
    # Generate and write code in workdir 
    # ... 
    # Compile and link into an .so/.dylib/.dll 
    # ... 
    lib = CDLL(path_to_lib) 
finally: 
    shutil.rmtree(workdir) 

雖然這似乎在* nix很好地工作系統我不確定它在Win32上的工作情況。這是因爲,根據我的經驗,當臨時目錄中的.dll映射到進程中時,不可能取消它。因此,rmtree將失敗。

我可以使用哪些選項來確保在Win32上.dll(以及它所在的目錄)儘快被刪除(因此,一旦底層lib被刪除或應用程序終止,不要留下暫時的殘餘物)。

回答

2

使用Kernel32函數FreeLibrary來取消映射該DLL並遞減其引用計數。要獲得句柄,您可以使用GetModuleHandleW,但它已經在_handle屬性中可用。

編輯:底層_ctypes模塊已經爲POSIX提供了此功能以及dlclose。如果出現錯誤,這些功能會提高WindowsError/OSError

>>> import os        
>>> from ctypes import * 
>>> from _ctypes import FreeLibrary 

>>> lib = CDLL('./lib.dll') 
>>> hlib = lib._handle 
>>> del lib 
>>> FreeLibrary(hlib) 

>>> os.remove('./lib.dll') 
>>> os.path.exists('./lib.dll') 
False 
+0

一般來說,人們希望在未確定的時間內使用'lib'。因此,我想知道是否可以說標記目錄和目錄刪除(所以Windows將處理清理)。 – 2013-03-22 08:52:57

+0

@FreddieWitherden:我還沒有看過。您可以註冊一個Python [atexit](http://docs.python.org/2/library/atexit)函數來釋放該庫並移除該目錄。 – eryksun 2013-03-22 08:57:26

+0

@FreddieWitherden您的評論與此問題不符。這個答案(+1)解決了你問的問題。如果你希望系統在不再使用的時候刪除一個DLL,我認爲這是不可能的。 – 2013-03-22 11:59:52