2014-05-07 42 views
3

,我發現有幾個職位在這裏有關卸載使用ctypes的一個dll,一個64位的DLL,我跟着完全相同的方式說是工作 從ctypes的導入*錯誤,當卸載使用ctypes的WINDLL

file = CDLL('file.dll') 

# do some stuff here 

handle = file._handle # obtain the DLL handle 

windll.kernel32.FreeLibrary(handle) 

然而,我是在蟒蛇64位和我的DLL也編譯爲x64和我從最後一行的錯誤說上面:

argument 1: <class 'OverflowError'>: int too long to convert 

我查手柄是「8791681138688一個長整型(Int64的) ',那麼這是否意味着windll.kernel32只處理int32句柄? Google搜索顯示kernal32也適用於64位窗口。那麼我該如何處理呢?

回答

3

FreeLibrary需要一個句柄,定義爲一個C void *指針。請參閱Windows Data Types。在設置這個函數指針的argtypes

import ctypes 
from ctypes import wintypes 

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)  
kernel32.FreeLibrary.argtypes = [wintypes.HMODULE] 

的缺省轉換一個Python intlong(在Python 3更名int)是一個C long,其隨後轉換爲一個C int。即使在64位Windows上,Microsoft也使用32位long,這就是爲什麼轉換引起OverflowError

在具有64位long(即幾乎所有其他64位操作系統)的平臺上,將指針作爲Python整數傳遞而不定義函數的argtypes可能實際上會對進程進行段錯誤。初始轉換爲long可以正常工作,因爲它與指針的大小相同。但是,隨後轉換爲32位C int可能會以靜默方式截斷該值。

+0

然後'kernel32.FreeLibrary(handle)',而不是'windll.kernel32.FreeLibrary(handle)',對吧? – endolith

+1

@endolith,是的,它定義了緩存在kernel32上的'FreeLibrary'函數指針的原型。最好避免使用'windll'加載器,因爲它是全局的,並且可能導致公用共享庫(如kernel32.dll)的包之間發生衝突。 – eryksun