在python 3.4.3和2.7.9中,当我试图调用内核库中的任何函数时。
从32位python版本在64位windows上,打印一个错误消息:
from ctypes import *
path=create_string_buffer(256)
rs=cdll.Kernel32.GetModuleFileNameA(0,path,256)
print (path)
Traceback (most recent call last):
File "test-ctypes.py", line 3, in <module>
ValueError: Procedure called with not enough arguments (12 bytes missing) or wrong calling convention
异常消息告诉您答案:
ValueError: 没有足够的参数(缺少12个字节)或调用约定错误
参数的数量是正确的,所以它一定是另一个:你使用了错误的调用约定。调用约定是编译器在调用函数时将C中的三个参数映射为在内存中存储实际值的方式(以及其他一些事情)。在GetModuleFileA的MSDN文档中,您可以找到以下签名
DWORD WINAPI GetModuleFileName(
_In_opt_ HMODULE hModule,
_Out_ LPTSTR lpFilename,
_In_ DWORD nSize
);
WINAPI
告诉编译器使用stdcall
调用约定。您的ctypes代码使用cdll
,另一方面,它假设cdecl
调用约定。解决方案很简单:将cdll
更改为windll
:
from ctypes import *
path=create_string_buffer(256)
rs=windll.Kernel32.GetModuleFileNameA(0,path,256)
print (path)
与访问.dll的ctypes文档相比,kernel32
被显式地显示为使用windll
。