user1720897
user1720897

Reputation: 1246

Python ctypes error - TypeError: an integer is required (got type LP_c_long)

I am trying to play around with Python and ctypes by experimenting with certain Windows APIs. I have a snippet of code that fails and I am not sure why. I have set all the argtypes and the return types as per the MSDN documentation. The error I am getting is: TypeError: an integer is required (got type LP_c_long). You can see all of the error in the output section. The thing is as far as I can tell the argtypes and return types are correct and I am not certain what needs fixing.

from ctypes import *
from ctypes import wintypes as w

user32 = windll.user32
kernel32 = windll.kernel32

HOOKPROC = WINFUNCTYPE(HRESULT, c_int, w.WPARAM, w.LPARAM)  # Callback function prototype

user32.SetWindowsHookExW.argtypes = [c_int, HOOKPROC, w.HINSTANCE, w.DWORD]
user32.SetWindowsHookExW.restype = w.HHOOK
   
kernel32.GetModuleHandleW.argtypes = [w.LPCWSTR]
kernel32.GetModuleHandleW.restype = w.HANDLE

user32.GetMessageW.argtypes = [w.LPMSG, w.HWND, w.UINT, w.UINT]
user32.GetMessageW.restype = w.BOOL

user32.CallNextHookEx.argtypes = [w.HHOOK, c_int, w.WPARAM, w.LPARAM]
user32.CallNextHookEx.restype = w.LPLONG

def hook_procedure(nCode, wParam, lParam):
   print("Hello...")
   #return user32.CallNextHookEx(hook, nCode, wParam, lParam)
   return user32.CallNextHookEx(hook, nCode, wParam, c_lParam)
   
ptr = HOOKPROC(hook_procedure)
        
hook = user32.SetWindowsHookExW(
    13,
    ptr,
    kernel32.GetModuleHandleW(None),
    0
)

msg = w.MSG()                             # MSG data structure
user32.GetMessageW(byref(msg), 0, 0, 0) # Wait for messages to be posted


Output:

Hello...
Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 262, in 'converting callback result'
TypeError: an integer is required (got type LP_c_long)
Exception ignored in: <function hook_procedure at 0x0000025C469551F0>

Upvotes: 0

Views: 1037

Answers (1)

Mark Tolonen
Mark Tolonen

Reputation: 177891

The problem is here:

user32.CallNextHookEx.restype = w.LPLONG

CallnextHookEx returns an LRESULT which in C is defined as a LONG_PTR. That isn't a pointer, but is an integer the size of a pointer (4 bytes on 32-bit systems, 8 bytes on 64-bit systems). wintypes doesn't have that type, but LPARAM has the same definition (LONG_PTR), so you can use the following for a definition that will work on 32- and 64-bit Python:

from ctypes import wintypes as w
LRESULT = w.LPARAM
...
user32.CallNextHookEx.restype = LRESULT

Upvotes: 1

Related Questions