2015-10-16 110 views
1

奇怪的行爲在Python的2.7.10:GetProcAddress的關於Python 3.4

>>> 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 

怎麼了,怎麼解決它(如果可能的話)?

回答

1

GetProcAddress在處理函數名稱的字符串方面有點不尋常。由於導出的函數名稱始終使用8位文本進行編碼,因此過程名稱參數的類型爲LPCSTR

Python 2.7字符串類型str不是Unicode,當傳遞到​​時,默認將文本編碼爲8位。 Python 3.x字符串類型是Unicode,當傳遞到​​時,默認將文本編碼爲16位。因此失敗。

使用argtypesrestype準確地說明類型並解決此問題。

 
>>> 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 
+0

非常感謝您的解釋!它的作品:windll.kernel32.GetProcAddress(windll.kernel32.GetModuleHandleW('kernel32'),b'LoadLibraryW') – kate