java dll 动态库 捕获鍵盤事件 全局变量的问题
下面是我写的一个取得全局键盘事件的VC文件,问题在于,
我还要回调我的java方法,
调java方法就要用到 JNIEnv* g_env;jclass g_jcs;这两个实例才能实现,
但监听windows键盘事件是回调的,我不能用做传参数的方式来得到这两个实例的指针,
我能想到最简单的办法是记它们做为静态变量,但问题还是出现了,好像整个dll被加载了很多次,
键盘事件所回调的dll实例与键盘事件回调的dll实例不相同,所以在回调方法中还是无法得到JNIEnv* g_env;jclass g_jcs;
这两个变量的指针,我对VC不熟,请各位大老帮帮忙,谢谢
// Hook.cpp : Defines the entry point for the DLL application.
#include "Hook.h"
#include "stdafx.h"
#include <string>
#include <cstdlib>
#include <string>
#include <sstream>
#include <iostream>
#include "org_csj_hook_JavaHook.h"
static HHOOK g_hkb=NULL;
static HINSTANCE g_hins;
static JNIEnv* g_env;
static jclass g_jcs;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
//MessageBox(NULL,"DllMain","测试",MB_OK);
if (g_hins == NULL) { //这里会被加载进入多次,说明它们不是同一实例
MessageBox(NULL,"DllMain","测试",MB_OK);
g_hins=(HINSTANCE)hModule;
}
//hins=::LoadLibrary("D:\\Java\\jdk1.5.0_06\\jre\\bin\\client\\jvm.dll");
return TRUE;
}
LRESULT __stdcall CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if(((DWORD)lParam&0x40000000) && (HC_ACTION==nCode))
{
MessageBox(NULL,"KeyboardProc","测试",MB_OK);
if(g_env){//这里的使终是false,说明它从来都没有被赋过值
MessageBox(NULL,"KeyboardProc->env","测试",MB_OK);
}
if(g_jcs){//这里的使终是false,说明它从来都没有被赋过值
MessageBox(NULL,"KeyboardProc->obj","测试",MB_OK);
}
//查找org.csj.hook.JavaHook类,返回JAVA类的CLASS对象
//jclass cls = env->FindClass("org/csj/hook/JavaHook");
//jclass cls = env->GetObjectClass(obj);
//if(cls){
// MessageBox(NULL,"cls","测试",MB_OK);
//}
//获取类中的方法,最后一个参数是方法的签名,通过javap -s -p 文件名可以获得
//jmethodID mid = env->GetMethodID(cls, "hookCallback","(III)V");
//if(mid){
// MessageBox(NULL,"mid","测试",MB_OK);
//}
//env->CallObjectMethod(obj, mid, 0, 1,2);
//unsigned int* a =(unsigned int*)wParam;
//unsigned long* b = (unsigned long*)lParam;
//MessageBox(NULL,a,"测试",MB_OK);
//MessageBox(NULL,"7777","测试",MB_OK);
//switch(wParam)
//{
//case '0':default;
//}
}
LRESULT RetVal = CallNextHookEx( g_hkb, nCode, wParam, lParam );
return RetVal;
}
//安装钩子
//BOOL __declspec(dllexport)__stdcall InstallHook()
JNIEXPORT jboolean JNICALL __stdcall Java_org_csj_hook_JavaHook_installHook
(JNIEnv * jenv, jclass jcs)
{
//hins=::LoadLibrary("G:\\winWorks\\Hook\\Debug\\Hook.dll");
g_hins=GetModuleHandle("G:\\winWorks\\Hook\\Debug\\Hook.dll");
//::FreeLibrary(g_hins);
if(g_hins){
g_hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,g_hins,0);
if(g_hkb){//这里已经可以为true,说明已经成功,而且到了这一步后只要你按键,KeyboardProc就会被回调
MessageBox(NULL,"installHook: true ","测试",MB_OK);
g_env = jenv;//这里对要使用的静态变量赋值
g_jcs = jcs;//这里对要使用的静态变量赋值
return TRUE;
}
}
MessageBox(NULL,"installHook: false ","测试",MB_OK);
return FALSE;
}
//释放钩子
//BOOL __declspec(dllexport) UnHook()
JNIEXPORT jboolean JNICALL __stdcall Java_org_csj_hook_JavaHook_unHook
(JNIEnv * jenv, jclass jcs)
{
if(g_env){//如果上面成功注册事件,那么这里都是为true,因为Java_org_csj_hook_JavaHook_installHook,Java_org_csj_hook_JavaHook_unHook这两个方法都是在java类中调用,所以它们应该是同一个实例
MessageBox(NULL,"unHook->env","测试",MB_OK);
}
if(g_jcs){//如果上面成功注册事件,那么这里都是为true,因为Java_org_csj_hook_JavaHook_installHook,Java_org_csj_hook_JavaHook_unHook这两个方法都是在java类中调用,所以它们应该是同一个实例
MessageBox(NULL,"unHook->obj","测试",MB_OK);
}
if(g_hkb){//这里都是true的.
BOOL unhooked = UnhookWindowsHookEx(g_hkb);
if(unhooked){
MessageBox(NULL,"unHook: true","测试",MB_OK);
return unhooked;
}
MessageBox(NULL,"unHook: false","测试",MB_OK);
//::FreeLibrary(hins);
return unhooked;
}
return false;
}
看问题好像就是实例的问题,不同实例的问题,我不专业,大家帮帮忙.