【问题标题】:GetProcAddress strange behaviour on Python 3.4Python 3.4 上的 GetProcAddress 奇怪行为
【发布时间】:2015-10-16 14:42:10
【问题描述】:

在 Python 2.7.10 上:

>>> from ctypes import windll
>>> windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleA('kernel32'), 'LoadLibraryW')

返回非空结果。但是在 Python 3.X 上也是一样的总是返回 null。

>>> from ctypes import windll
>>> windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleA('kernel32'), 'LoadLibraryA')
0
# and other variants
>>> windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleA('kernel32'), 'LoadLibraryW')
0
>>> windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleW('kernel32'), 'LoadLibraryA')
0
>>> windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleW('kernel32'), 'LoadLibraryW')
0

出了什么问题以及如何解决(如果可能的话)?

【问题讨论】:

    标签: python python-2.7 python-3.x winapi ctypes


    【解决方案1】:

    GetProcAddress 在处理函数名字符串方面有点不寻常。因为导出的函数名称总是用 8 位文本编码,所以过程名称参数的类型为 LPCSTR

    Python 2.7 字符串类型 str 不是 Unicode,当传递给 ctypes 时,默认将文本编码为 8 位。 Python 3.x 字符串类型是 Unicode,当传递给 ctypes 时,默认将文本编码为 16 位。因此失败了。

    使用argtypesrestype 来准确了解类型并解决此问题。

    >>> from ctypes import * # 只为了这个答案,省去打字 >>> GetModuleHandle = windll.kernel32.GetModuleHandleW >>> GetModuleHandle.argtypes = [c_wchar_p] >>> GetModuleHandle.restype = c_void_p >>> kernel32 = GetModuleHandle('kernel32') >>> 内核32 2004418560 >>> 2004418560 2004418560 >>> GetProcAddress = windll.kernel32.GetProcAddress >>> GetProcAddress.argtypes = [c_void_p, c_char_p] >>> GetProcAddress.restype = c_void_p >>> LoadLibraryW = GetProcAddress(kernel32, b'LoadLibraryW') # 强制 8 位编码 >>> 加载库W 2004509856

    【讨论】:

    • 非常感谢您的解释!它的工作原理:windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleW('kernel32'), b'LoadLibraryW')
    猜你喜欢
    • 1970-01-01
    • 2020-10-22
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多