2016-07-24 7 views
1

私はそのようにPythonでマウスフックを設定してい: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を行うまで

すべてが正常に動作しているようだループ内で呼ばれています同じアプリ内からのマウスクリックをシミュレートします。クリックをシミュレートすると、クラッシュが発生します。何が原因である可能性がありますか?

ありがとうございました。

+0

'GetModuleHandle'は、モジュールのベースアドレスへのポインタを返します。一般に、64ビットサポートのためには、 'restype'属性を' c_void_p'のようなポインタ型に設定する必要があります。また 'WPARAM'は符号なしとポインタのサイズです。このために 'c_void_p'を使うことができます。 – eryksun

+1

'ctypes.windll'の使用を避けてください。これは間違いなくctypesで最悪のことです。これは、関数ポインタをキャッシュするライブラリをキャッシュするため、使用されているモジュールがロードされたctypesが何であっても、あなたを魅了します。代わりに 'user32 = ctypes.WinDLL( 'user32'、use_last_error = True)'を使用してください。 – eryksun

+0

@eryksunありがとう、あなたは私のためにそれを修正! – Andrew

答えて

1

def low_level_handlerが範囲外になり、ガベージコレクション(?)/メモリから削除されたようです。私がdefリスニングからそれを動かした後、それはすべて動作しています。

+0

はい、コールバックはトランポリンコードの実行可能メモリの小さなブロックを割り当てる必要があります。これはCコードに渡されるポインタアドレスです。コールバックとそのトランポリンの割り当てが解除されないように、コールバックへの参照を保持する必要があります。 – eryksun