【问题标题】:python windows mouse hook crashpython windows鼠标钩子崩溃
【发布时间】:2016-07-24 22:56:34
【问题描述】:

我正在像这样在 python 中设置鼠标钩子:

def listen():
    global hook_id

    def low_level_handler(aCode, wParam, lParam):
        if aCode != win32con.HC_ACTION:
            return ctypes.windll.user32.CallNextHookEx(hook_id, aCode, wParam, lParam)

        return ctypes.windll.user32.CallNextHookEx(hook_id, aCode, wParam, lParam)

    # Our low level handler signature.
    CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_void_p))
    # Convert the Python handler into C pointer.
    pointer = CMPFUNC(low_level_handler)


    # Hook both key up and key down events for common keys (non-system).
    hook_id = ctypes.windll.user32.SetWindowsHookExA(win32con.WH_MOUSE_LL, pointer,
                                             GetModuleHandle(None), 0)
    # Register to remove the hook when the interpreter exits. Unfortunately a
    # try/finally block doesn't seem to work here.
    atexit.register(ctypes.windll.user32.UnhookWindowsHookEx, hook_id)

def process_msg():
    while True:
        status, msg = PeekMessage(None, 0, 0, win32con.PM_REMOVE)
        if status == 0:
            break
        TranslateMessage(ctypes.byref(msg))
        DispatchMessage(ctypes.byref(msg))

process_msg 随后在循环中被调用

一切似乎都工作正常,直到我在同一个应用程序中模拟鼠标点击的 SendInput。一旦我模拟点击,就会发生崩溃。可能是什么原因?

谢谢。

【问题讨论】:

  • GetModuleHandle 返回一个指向模块基地址的指针。通常,对于 64 位支持,您需要将其 restype 属性设置为指针类型,例如 c_void_pWPARAM 也是无符号的并且是指针的大小;您可以为此使用c_void_p
  • 避免使用ctypes.windll。这无疑是 ctypes 中最糟糕的事情。它使您受到碰巧加载的任何使用 ctypes 的模块的支配,因为它缓存了库,这些库缓存了函数指针。而是使用user32 = ctypes.WinDLL('user32', use_last_error=True)
  • @eryksun 谢谢,你帮我修好了!

标签: python windows hook mouse


【解决方案1】:

看起来 def low_level_handler 超出范围并被垃圾收集(?)/从内存中删除。在我将其移出 def listen 后,一切正常。

【讨论】:

  • 是的,回调必须为蹦床代码分配一小块可执行内存,这是传递给 C 代码的指针地址。您必须保留对回调的引用,以防止回调及其蹦床被释放。
猜你喜欢
  • 2014-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多