2011-04-11 3 views
0

저는 C로 DLL을 작성하려고합니다.Python에서 KeyboardHookProc을 호출해도 아무런 변화가 없습니다.

설치 후크는 KeyboardProc을 설정합니다. 파이썬에서 InstallHook()UninstallHook() 함수를 호출하면 콜백 함수 KeyboardProc이 작동하지 않기 때문에 항상 0을 반환합니다.

>>> from ctypes import * 
>>> dll = CDLL('C:\...\OurDLL.dll') 
>>> dll.InstallHook() 

[이 시점에서 입력 뭔가]

>>> result = dll.UninstallHook() 
>>> result 
0 
다음과 같이이가 사용하는

#include "stdafx.h" 
#include <windows.h> 
#include <string.h> 
#include <ctype.h> 
#include <stdio.h> 
#include "ourdll.h" 

//#pragma comment(linker, "/SECTION:.SHARED,RWS") 
//#pragma data_seg(".SHARED") 
HHOOK hKeyboardHook = 0; 
int keypresses = 0; 
    HMODULE hInstance = 0; 

//#pragma data_seg() 

BOOL WINAPI DllMain (HANDLE hModule, DWORD dwFunction, LPVOID lpNot) 
{ 
      hInstance = hModule; //Edit 
    return TRUE; 
} 

LRESULT CALLBACK KeyboardProc(int hookCode, WPARAM vKeyCode, LPARAM flags) 
{ 
    if(hookCode < 0) 
    { 
     return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags); 
    } 

    keypresses++;; 

    return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags); 
} 

__declspec(dllexport) void InstallHook(void) 
{ 
    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0); 
} 

__declspec(dllexport) int UninstallHook(void) 
{ 
    UnhookWindowsHookEx(hKeyboardHook); 
    hKeyboardHook = 0; 
    return keypresses; 
} 

파이썬 코드 :

다음

은 DLL 내 C 코드

편집 : 아마도 나는 LowLevelKeyboardHook도 시도했다고 언급해야합니다. 나는 LowLevel hook이 전역 적이며 모든 키 스트로크를 잡아낼 것이라고 생각하지만, 단지 dll.InstallHook() 파이썬 코드가 제로를 반환하기 전에 잠깐 동안 얼어 붙었다.

저는 C 전문가가 아니므로 도움을 주시면 대단히 감사하겠습니다. 감사.

답변

1
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0); 

SetWindowsHookEx에는 hModule이 필요합니다. hModule을 DllMain에서 저장하고 여기에 전달하십시오. (스레드 ID가 자신의 스레드 인 경우에만 NULL을 전달할 수 있습니다.)

한 가지 예외는 _LL 후크 유형입니다. 이러한 훅은 대상 프로세스에 삽입되지 않으므로 hmodule 매개 변수가 필요하지 않습니다. 이것이 KEYBOARD_LL을 사용하는 코드가 '성공'하는 이유입니다.

LowLevelKeyboardHookProc에 KEYBOARD_LL - docs를 사용할 때 차단되는 이유는 (즉, SetWindowsHookEx를 호출하는) 스레드가 Python 코드에없는 메시지 루프를 가지고 있어야한다는 것입니다.

디버깅 정보 : SetWindowsHookEx가 NULL을 반환해야합니다 (적절한 오류 코드를 반환하는 GetLastError() 사용). assert/printf/OutputDebugString의 조합을 적절히 사용하여 코드를 개발하는 동안 이러한 반환 값을 확인하는 것이 가정이 정확함을 보장하고 문제가 발생하는 위치에 대한 단서를 제공하는 좋은 방법입니다.

키보드 대 KEYBOARD_LL에 대해 알아야 할 또 하나의 사항 : KEYBOARD_LL과 비교하여 KEYBOARD_LL은 대상 프로세스에로드됩니다. 그러나 이것이 동일한 비트 일 경우에만 가능합니다. 따라서 32 비트 훅은 다른 32 비트 프로세스. OTOH, KEYBOARD_LL은 자신의 프로세스에서 다시 호출되므로 모든 키를 볼 수 있습니다. 또한 공유 세그먼트를 처리 할 필요가 없습니다 (키프 로크만큼 효율적이지는 않지만).

+0

네가 맞아! DLLMain에서'HMODULE' 타입을 저장해야했습니다. 이제는'KeyboardProc' 콜백 함수에서'keypresses' 값을 증가시키고 있습니다. 공유 세그먼트는 Lowlevel 키보드를 시도 할 때 남겨둔 코드입니다. 내 실수 코드에 대한 사과, 나는 그것을 부끄럽게 여긴다.하지만 실제로 사용하기 전에 해결할 것이다. 다시 한번, 많은 감사합니다! – mmoore

관련 문제