在 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
出了什么问题以及如何修复它(如果可能的话)?
最佳答案
GetProcAddress
在处理函数名称字符串方面有点不寻常。由于导出的函数名称始终使用 8 位文本进行编码,因此过程名称参数的类型为 LPCSTR
。
Python 2.7 字符串类型,str
不是 Unicode,当传递给 ctypes
时,默认将文本编码为 8 位。 Python 3.x 字符串类型是 Unicode,当传递给 ctypes 时,默认将文本编码为 16 位。因此失败了。
使用argtypes
和restype
来精确了解类型并解决这个问题。
>>> from ctypes import * # just for this answer, to save typing >>> GetModuleHandle = windll.kernel32.GetModuleHandleW >>> GetModuleHandle.argtypes = [c_wchar_p] >>> GetModuleHandle.restype = c_void_p >>> kernel32 = GetModuleHandle('kernel32') >>> kernel32 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') # force 8 bit encoding >>> LoadLibraryW 2004509856
关于python - Python 3.4 上的 GetProcAddress 奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33173251/