首先,您必须定义一个管理器类,类似于:
package foo.bar
public class SomeHookManager {
public static void initialize (...) {
// <pre-initialization-routing>
_native_init_();
// <post-initialization-routing>
}
public static void registerCallback (IHookCallback callback)
{ /* save this callback */ }
// this method will be invoked in your C code.
protected static void invokeCallback () { /* invoke the saved callback */ }
// this is a native method, the native modifier tells the compiler this method
// is implemented in C, and linked at runtime.
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 项目,包含此文件并实现此方法。确保在触发实际挂钩时,调用invokeCallback您的 C 代码:
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 位于同一文件夹中。或-Djava.library.path=/path/to/your/dlls在 VM 参数中指定。
至于如何记录每个按键,操作系统通常会提供一些 API 来拦截按键事件。对于 Windows 系统,您可以通过拦截全局密钥消息来实现此目的。我在其他系统上没有任何经验。无论如何,您可以设置适当的中断,这是安静的低级。你可以随时用谷歌搜索你的答案。:)