日期:2014-05-20  浏览次数:22376 次

JNI调用HOOK的问题,设置共享变量无效,调了蛮久了解决不了,弄过的兄弟帮忙了,谢了。
需要实现实现系统托盘,以及热键恢复窗口。默认Ctrl+Alt+任意键。
#include   <jni.h>
typedef   struct   HotKeyEntry
{
JNIEnv*   env;
jobject   callBackObject;
int*   hotKeyCodes;
int     hotKeyCount;
}   *PHotKeyEntry;
   
#pragma   data_seg( ".JOE ")
PHotKeyEntry   pHotKeyEntry   =   NULL;
#pragma   data_seg()
#pragma   comment(linker, "/SECTION:.JOE,rws ")


void   showKeyInfo(int   nCode,   WPARAM   wParam,   LPARAM   lParam)   {

if   (pHotKeyEntry   ==   NULL   ||   pHotKeyEntry-> hotKeyCodes   ==   NULL)   {
MessageBox(NULL,   TEXT( "Strange!!!pHotKeyEntry!!NULL "),   TEXT( "Strange!!!pHotKeyEntry!!NULL "),   MB_OK);
return;
}
}

LRESULT   CALLBACK   LowLevelKeyboardProc(int   nCode,   WPARAM   wParam,   LPARAM   lParam)   {
        showKeyInfo(nCode,   wParam,   lParam);
return   CallNextHookEx(0,   nCode,   wParam,   lParam);
}

JNIEXPORT   jboolean   JNICALL   Java_com_gy_image_HotKeyHookManager_startHotKeyHook(JNIEnv   *   env,  
        jobject   hotKeyManagerObj,   jobject   hotKeyCallBackObj)   {
       
        //Get   the   KeyCodes.
jintArray   hotKeyCodeArray   =   getInstanceIntArrayField(env,   hotKeyManagerObj);
int   hotKeyCount   =   env-> GetArrayLength(hotKeyCodeArray);
int*   hotKeyCodes   =   new   int[hotKeyCount];
jint*   rawIntArray   =   env-> GetIntArrayElements(hotKeyCodeArray,   0);
for   (int   i   =   0;   i   <   hotKeyCount;   ++i)   {
        hotKeyCodes[i]   =   rawIntArray[i];
}
env-> ReleaseIntArrayElements(hotKeyCodeArray,   rawIntArray,   0);
if   (pHotKeyEntry   ==   NULL)   {
pHotKeyEntry   =   new   HotKeyEntry;
pHotKeyEntry-> env   =   env;
pHotKeyEntry-> callBackObject   =   hotKeyCallBackObj;
pHotKeyEntry-> hotKeyCodes   =   hotKeyCodes;
pHotKeyEntry-> hotKeyCount   =   hotKeyCount;
}

hhook   =   SetWindowsHookEx(WH_KEYBOARD,   LowLevelKeyboardProc,   dllModule,   NULL);
if   (hhook   ==   NULL)   {
releaseHotKeyHook();
MessageBox(NULL,   TEXT( "SetWindoesHook   fail "),   TEXT( "SetWindowsHook   fail "),   MB_OK);
                return   FALSE;
}

return   TRUE;
}


一堆问题:
1。在任意窗口按键,回调是能捕获输入的,HotKeyEntry包含了我设置的热键keyCode以及Java里面的回调对象callBackObject(JFrame),   原本想保存这些东西,等到特定的键触发的时候恢复JFrame;   但是很可惜HotKeyEntry总是空的,网上说#pragma   comment(linker, "/SECTION:.JOE,rws ")说可以共享数据,但是为什么总是不生效呢?用的是VS2005,把/SECTION设置在Project的Linker的Commandline也不行,   请问如果保存这些数据?
2.MSDN说HOOK是要调DLL好,创建HOOK和回调要分开,我就又把CALLBACK写成DLL来调,   HotKeyEntry也传过去了,问题还是一样,   回调里面有字符扑获,但是不同窗口出发按键打印的HotKeyEntry都是空的,除非在Java的Frame里面就没问题。  
3.后来都懵了,以为是要用底层的KeyBoardHook,我就又设置SetWindowsHookEx为WH_KEYBOARD_LL,继续尝试1,2步骤,结果更死,回调根本没东西打出来,点一下键盘还卡死一下,应该是没响应PENDING了,准备直接用VC写写看了。
是不是JNI里面这些线程还是什么影响了DLL跟普通window编程不同呢?还是哪里弄错了,   弄过的兄弟帮忙下了,谢了。