【问题标题】:error when unload a 64bit dll using ctypes windll使用 ctypes windll 卸载 64 位 dll 时出错
【发布时间】:2014-05-07 15:29:37
【问题描述】:

我发现这里有几篇关于使用 ctypes 卸载 dll 的帖子,我完全按照所说的工作方式进行操作 从 ctypes 导入 *

file = CDLL('file.dll')

# do some stuff here

handle = file._handle # obtain the DLL handle

windll.kernel32.FreeLibrary(handle)

但是,我在 python 64 位上,我的 dll 也是为 x64 编译的,我从上面的最后一行得到一个错误:

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

并且我检查了句柄是'8791681138688'的长整数(int64),那么这是否意味着windll.kernel32只处理int32句柄?谷歌搜索显示 kernal32 也适用于 64 位窗口。那我该怎么处理呢?

【问题讨论】:

    标签: python 64-bit ctypes


    【解决方案1】:

    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 可能会静默截断该值。

    【讨论】:

    • 然后是kernel32.FreeLibrary(handle),而不是windll.kernel32.FreeLibrary(handle),对吧?
    • @endolith,是的,这定义了缓存在kernel32 上的FreeLibrary 函数指针的原型。最好避免使用 windll 加载器,因为它是全局的,并且可能导致常见共享库(如 kernel32.dll)的包之间发生冲突。
    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2010-09-26
    • 2013-01-28
    • 1970-01-01
    • 2018-01-26
    • 2016-03-06
    • 1970-01-01
    • 2011-01-21
    相关资源
    最近更新 更多