首先您需要定义一个管理器类,大致如下:
package foo.bar
public class SomeHookManager {
public static void initialize (...) {
_native_init_();
}
public static void registerCallback (IHookCallback callback)
{ }
protected static void invokeCallback () { }
protected native static void _native_init_ ();
}
然后使用 javah
生成一个 C 头文件,结果类似于(我并没有实际编译这段代码,因此这只是假设):
/*
* Class: Win32
* Method: _native_init_
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_foo_bar_Win32_native_init_
(JNIEnv * env, jobject obj);
创建一个C项目,包含此文件并实现此方法。确保在实际钩子触发时,在您的C代码中调用
invokeCallback
:
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mId = (*env)->GetStaticMethodID(env, cls, "invokeCallback", "()V");
if (mId == 0) { /* error handling */ }
(*env)->CallStaticVoidMethod(env, cls, mId);
把C项目编译成一个DLL文件,比如说hookimpl_win32.dll
,然后在Java代码的某个位置进行动态链接:
static {
System.loadLibrary("hookimpl_win32"); // no need of .dll or .so in Unix alike OS's
}
确保dll文件与您的jar文件在同一文件夹中。或者在VM参数中指定-Djava.library.path=/path/to/your/dlls
。
至于如何记录每个按键,操作系统通常提供一些API来拦截键盘事件。对于Windows系统,您可以通过拦截全局键消息来实现此目的。我没有其他系统的经验。无论如何,您可以设置适当的中断,这是相当低级的。您总是可以通过谷歌找到答案。 :)