python-2.7python-3.xctypeswindows64

Python 32bit on Windows 64bit Ctypes module error


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

Solution

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