我尝试在java代码中获取该方法的jMethodID
,但是当我调用此特定函数时,会抛出异常:
Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: displayKeyStrokes
at org.suhail.keylogger.HelperClasses.NativeMethods.initializeJNIVars(Native Method)
at org.suhail.keylogger.GUI.MainGUI.jMenuItem1ActionPerformed(MainGUI.java:356)
.
.
.
我不明白这个的原因。以下是从java方法调用的 C 代码段:
void Java_org_suhail_keylogger_HelperClasses_NativeMethods_initializeJNIVars
(JNIEnv *env, jobject obj) {
jclass cls = (*env)->GetObjectClass(env,obj);
callBackToDeliverKeyStroke = (*env)->GetMethodID(env,cls,"displayKeyStrokes","()V");
object = (*env)->NewGlobalRef(env,obj);
if(object == NULL | callBackToDeliverKeyStroke == NULL | cls == NULL) {
printf("Initialization error...One of the variable is Null\n");
}
}
这是java代码中名为displayKeyStrokes
的方法:
public void displayKeyStrokes() {
System.out.println("Java Message : A Key has been pressed");
}
我得到例外的原因是什么?
调用JNI代码的Java代码:
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem1.setEnabled(false);
jMenuItem2.setEnabled(true);
try {
System.loadLibrary("Dll_PKeylogger"); // Load the dll written to listen to the tapping of keys
nativeMethods.initializeJNIVars(); // CALL
}catch(Exception exc) {
exc.printStackTrace();
}
}
NativeMethods Class (声明本机方法)
package org.suhail.keylogger.HelperClasses;
public class NativeMethods {
public native void initializeJNIVars();
public native void unregisterHook();
}
注意: 我在另一个名为initializeJNIVars
的类的对象上调用方法NativeMethods
,方法jMenuItem1ActionPerformed
是每当事件发生时从匿名内部类调用:
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem1ActionPerformed(evt);
}
});
答案 0 :(得分:1)
你说:
jMenuItem1ActionPerformed是从一个匿名类调用的,该类与displayKeyStrokes在同一个类中。是的jMenuItem1ActionPerformed与jMenuItem1ActionPerformed属于同一个类,除非它是从匿名内部类调用的,如下所示
那可能是你的问题。存在于匿名内部类中的jMenuItem1ActionPerformed很重要,这意味着它与jMenuItem1ActionPerformed位于不同的类中,并且当您尝试从JNI C代码中获取方法ID时,需要将其考虑在内。
考虑为您的initializeJNIVars()
方法提供一个参数,该参数接受外部类的实例,然后将该实例传递给参数,并在调用GetMethodID(...)
时使用它。请注意,您必须将参数传递为OuterClassName.this
。
答案 1 :(得分:0)
您获得的例外描述是:
如果应用程序尝试调用类的指定方法,则抛出该异常 (静态或实例),该类不再具有定义 那种方法。
通常,编译器会捕获此错误;这个错误只能 如果类的定义不兼容,则在运行时发生 改变。
您的代码线程是否分开?当你试图调用这个方法时,一个已经死的线程是否有可能加载displayKeyStrokes方法?