in both python 3.4.3 and 2.7.9 when I try to call any function from kernel library.
from 32bit version of python on 64bit windows, an error message is printed:
from ctypes import *
path=create_string_buffer(256)
rs=cdll.Kernel32.GetModuleFileNameA(0,path,256)
print (path)
the error is as following :
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
The exception message tells you the answer:
ValueError: Procedure called with not enough arguments (12 bytes missing) or wrong calling convention
The number of arguments is right, so it must be the other: You are using the wrong calling convention. The calling convention is the way the compiler maps the three arguments in C into a way to store the actual values in memory when calling the function (among a few other things). On the MSDN documentation for GetModuleFileA you find the following signature
DWORD WINAPI GetModuleFileName(
_In_opt_ HMODULE hModule,
_Out_ LPTSTR lpFilename,
_In_ DWORD nSize
);
The WINAPI
tells the compiler to use the stdcall
calling convention. Your ctypes code uses cdll
which on the other hand assumes cdecl
calling convetion. The solution is simple: change cdll
to windll
:
from ctypes import *
path=create_string_buffer(256)
rs=windll.Kernel32.GetModuleFileNameA(0,path,256)
print (path)
Compare with the ctypes documentation for accessing .dll's, where kernel32
is explicitely shown to use windll
.