使用ctypes windll卸载64位DLL时出错
我发现这里有好几个帖子在讨论如何使用ctypes卸载一个dll文件,我按照上面说的方法一步步做的。
file = CDLL('file.dll')
# do some stuff here
handle = file._handle # obtain the DLL handle
windll.kernel32.FreeLibrary(handle)
不过,我用的是64位的Python,而我的dll也是为x64编译的,结果在上面的最后一行出现了错误:
argument 1: <class 'OverflowError'>: int too long to convert
我检查了一下句柄,发现它是一个长整型(int64),值是'8791681138688'。这是不是意味着windll.kernel32只处理int32的句柄?我在谷歌上查了一下,发现kernel32也是支持64位Windows的。那么我该怎么处理这个问题呢?
1 个回答
11
FreeLibrary
是一个函数,它需要一个句柄,这个句柄在C语言中是用 void *
指针来表示的。你可以查看 Windows数据类型 来了解更多。你需要在函数指针的 argtypes
中设置这个句柄:
import ctypes
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
kernel32.FreeLibrary.argtypes = [wintypes.HMODULE]
在Python中,默认情况下,int
或 long
(在Python 3中被称为 int
)会被转换成C语言中的 long
,然后再转成C语言中的 int
。微软在64位Windows上也使用32位的 long
,这就是为什么转换时会出现 OverflowError
的原因。
在那些有64位 long
的平台上(几乎所有其他的64位操作系统都是这样),如果你把一个指针当作Python整数传递,而没有定义函数的 argtypes
,可能会导致程序崩溃。最开始转换成 long
是没问题的,因为它和指针的大小是一样的。但是,后面再转换成32位的C int
时,可能会悄悄地截断这个值。