我正在尝试使用ctypes,我无法调用FormatMessage()来正常工作。
这是我到目前为止的代码;我认为唯一的问题是传递一个可变缓冲区;我从ctypes得到一个关于lpBuffer
的ArgumentErrorimport ctypes
from ctypes.wintypes import DWORD
def main():
fm = ctypes.windll.kernel32.FormatMessageA
fm.argtypes = [DWORD,DWORD,DWORD,DWORD,ctypes.wintypes.LPWSTR(),DWORD]
dwFlags = DWORD(0x1000) # FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM
lpSource = DWORD(0)
dwMessageId = DWORD(0x05)
dwLanguageId = DWORD(0)
#buf = ctypes.wintypes.LPWSTR()
#lpBuffer = ctypes.byref(buf)
lpBuffer = ctypes.create_string_buffer(512)
nSize = DWORD(512)
res = fm(dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize)
print res
我在lpBuffer参数上遇到一个错误,说它是一个错误的类型,但我已经尝试了尽可能多的传入缓冲区的变体。我尝试过这样做:https://gist.github.com/CBWhiz/6135237并设置FORMAT_MESSAGE_ALLOCATE_BUFFER然后传入LPWSTR()byref,我也尝试将argtype,指针和转换更改为各种LPWSTR(),c_char_p等,但无论我做什么,它都在抱怨。
使函数正确执行的正确语法是什么?我知道ctypes可能很有问题,但我没有在文档中找到任何解决问题的东西(我知道文档使用prototype()但我现在想以这种方式这样做)
谢谢
答案 0 :(得分:1)
以下是argtypes
的{{1}}定义(对于Unicode,请注意“W”):
FormatMessageW
如果import ctypes
from ctypes import wintypes
fm = ctypes.windll.kernel32.FormatMessageW
fm.argtypes = [
wintypes.DWORD, # dwFlags
wintypes.LPCVOID, # lpSource
wintypes.DWORD, # dwMessageId
wintypes.DWORD, # dwLanguageId
wintypes.LPWSTR, # lpBuffer
wintypes.DWORD, # nSize
wintypes.LPVOID, # Arguments (va_list *)
]
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100
FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
分配缓冲区,则必须将引用传递给FormatMessage
。只需lpBuffer
参考即可绕过cast
。另外,记得调用TypeError
来释放缓冲区:
kernel32.LocalFree