简体   繁体   English

一个函数多次调用:为什么? 和通过C线程使用不当?

[英]one function called multiple times : why ? and improper use of threading through C?

Through the following code i tried to implement a simple keystroke catcher. 通过以下代码,我试图实现一个简单的按键捕捉器。 When the user taps a key,he gets notified. 当用户点击一个键时,他会收到通知。 Java code loads the dll which runs the DllMain method from where it also starts a new thread.` Java代码加载dll它运行DllMain从那里也开始了新的thread.`方法

Java code loads a library in the static block.The dll has the DllMain method which executes and prints some statements.It also a starts a new thread from the DllMain . Java代码在静态块中加载一个库dll具有DllMain方法,该方法执行并打印一些语句。它还从DllMain启动一个新线程。 A new thread is also started in the java program which sleeps for 2 milliseconds.From the output it seems that DllMain , installHook are called multiple times. 同样在Java程序中启动了一个新线程,该线程休眠了2毫秒。从输出看来, DllMaininstallHook被多次调用了。 Why is that ? 这是为什么 ? What is the problem ? 问题是什么 ?

Though the user is notified when the key is tapped why the same function is called multiple times ? 尽管在敲击按键时会通知用户,为什么多次调用同一功能? I think i have implemented the function installHook or implemented the thread logic in a poor manner. 我认为我已经实现了功能installHook或以不良的方式实现了线程逻辑。

Java Code : Java代码:

package keylogger;

public class TestKeys {
private static int i = 0;
private native void setWinHook();
private native void unregisterWinHook();

public static void main(String args[]) {

    //TestKeys o = new TestKeys();


    System.out.println("After the call to load library !");

    Runnable r = new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println("Sleeping...");
                Thread.sleep(2);
            }catch(Exception exc) {
                exc.printStackTrace();
            }
        }
    };
    new Thread(r,"new thread").start();       
}

static {
    System.loadLibrary("MyHook");
}
}

C Code : C代码:

#include <stdio.h>
#include <windows.h>
#include <w32api.h>
#include "keylogger_TestKeys.h"

static HHOOK handleKeyboardHook = NULL;
HINSTANCE hInst = NULL;
static DWORD hookThreadId = 0;
static HANDLE hookThreadHandle = NULL;
BOOL WINAPI installHook(HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved);

static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
 printf("You pressed the key !\n");
 return CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam);
}

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved) {
  LPTHREAD_START_ROUTINE lpStartAddress = &installHook;
  printf("From DllMain : %u\n",fwdReason);
  hookThreadHandle = CreateThread(NULL, 0, lpStartAddress, NULL, 0, &hookThreadId);
  if(hookThreadHandle == NULL) {
    printf("\nhookThreadHandle is NULL\n");
  }
  return TRUE;
}

JNIEXPORT void JNICALL Java_keylogger_TestKeys_unregisterWinHook
 (JNIEnv *env, jobject obj) {
   if(handleKeyboardHook != NULL) {
    UnhookWindowsHookEx(handleKeyboardHook);
    printf("Keyboard hook successfully unregistered !");
   } else {
      printf("Coudn't Unhook the keyboard hook !");
     }
} 

BOOL WINAPI installHook(HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved) {
printf("From installHook : %u",fwdReason);
handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hinstDLL, 0);
MSG msg;

while(GetMessage(&msg, NULL, 0, 0))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}
return msg.wParam;

} }

Output : 输出:

From DllMain : 1
From DllMain : 2
From installHook : 66321916From DllMain : 2
After the call to load library !From installHook : 65797624
From DllMain : 2
From installHook : 67304108From DllMain : 2
From installHook : 60423404From DllMain : 2
From installHook : 67893304From DllMain : 2
From installHook : 68484828From DllMain : 2
From installHook : 69204012From DllMain : 2 
From installHook : 61799988From DllMain : 2
From installHook : 62847812From DllMain : 2
From DllMain : 2
Sleeping... 
From installHook : 71695184From DllMain : 2
From installHook : 70907884From DllMain : 2
From installHook : 70581032From DllMain : 2
From installHook : 72219984From DllMain : 2
From installHook : 73071020From DllMain : 2
From installHook : 66649544From DllMain : 2
From installHook : 73399648From DllMain : 3
From DllMain : 2
From DllMain : 3
From installHook : 73858604From DllMain : 2
From DllMain : 3
From installHook : 75955548From DllMain : 3
From DllMain : 2
From installHook : 72548100From DllMain : 2
From installHook : 74643796From DllMain : 2
From installHook : 75560952From DllMain : 3
From DllMain : 2
From installHook : 71236420From DllMain : 2
From installHook : 74316888From DllMain : 2
From installHook : 77265476From DllMain : 0

hookThreadHandle is NULL

From the DllMain documentation: DllMain文档中:

An optional entry point into a dynamic-link library (DLL). 动态链接库(DLL)的可选入口点。 When the system starts or terminates a process or thread , it calls the entry-point function for each loaded DLL using the first thread of the process. 当系统启动或终止进程或线程时 ,它将使用进程的第一个线程为每个加载的DLL调用入口点函数。 The system also calls the entry-point function for a DLL when it is loaded or unloaded using the LoadLibrary and FreeLibrary functions. 当使用LoadLibrary和FreeLibrary函数加载或卸载DLL时,系统还会调用DLL的入口点函数。

Since you're creating a thread in that function, you've essentially got an infinite loop there - DllMain (on load) creates a thread, so DllMain is called, that starts a thread, so DllMain is called ... 由于您是在该函数中创建线程的,因此实际上在其中有一个无限循环DllMain (在加载时)创建了一个线程,因此DllMain ,它启动了一个线程,因此, DllMain

Read that documentation very carefully, you should probably not be doing anything if the reason is not DLL_PROCESS_ATTACH ( 1 ). 请仔细阅读该文档,如果原因不是DLL_PROCESS_ATTACH1 ),则可能不应该做任何事情。 (I'm not actually sure if starting a thread from that procedure is legal.) (我实际上不确定从该过程启动线程是否合法。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM