Make sure to define the .argtypes
and .restype
of the functions you are using with ctypes
. GetModuleHandleA
takes a LPCSTR
(equivalent to a bytes
object in Python), and GetModuleHandleW
takes a LPCWSTR
(equivalent to a str
object in Python). Additionally, they both return HDMODULE
, which is a 64-bit value of 64-bit systems, but the default .restype
if unspecified is c_int
(32-bit).
Here's correct code to call either version:
import ctypes as ct
from ctypes import wintypes as w
k32 = ct.WinDLL('kernel32')
k32.GetModuleHandleA.argtypes = w.LPCSTR,
k32.GetModuleHandleA.restype = w.HMODULE
k32.GetModuleHandleW.argtypes = w.LPCWSTR,
k32.GetModuleHandleW.restype = w.HMODULE
wmi = ct.WinDLL('wmi')
print(k32.GetModuleHandleA(b'wmi')) # byte string
print(k32.GetModuleHandleW('wmi')) # Unicode string
print(k32.GetModuleHandleA('wmi')) # calling with wrong type
Sample output below. Note this value is larger than a 32-bit value could hold (>4294967295) and would be truncated and incorrect if .restype
wasn't set, and the error message would not occur if .argtypes
wasn't set.
1864530853888
1864530853888
Traceback (most recent call last):
File "C:\test.py", line 15, in <module>
print(k32.GetModuleHandleA('wmi'))
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type