2

我尝试jMethodID在 java 代码中获取该方法,但是当我调用这个特定函数时,会引发异常:

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");
 }
}

这是displayKeyStrokesjava代码中命名的方法:

 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 类(声明本机方法)

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);
        }
    });
4

2 回答 2

1

你说:

jMenuItem1ActionPerformed 是从与 displayKeyStrokes 位于同一类内的匿名类调用的。是的,jMenuItem1ActionPerformed 与 jMenuItem1ActionPerformed 属于同一类,只是它是从匿名内部类调用的,如下所示

那很可能是你的问题。位于匿名内部类中的 jMenuItem1ActionPerformed 很重要,这意味着它与 jMenuItem1ActionPerformed 位于不同的类中,当您尝试从 JNI C 代码中获取方法 ID 时需要考虑这一点。

考虑为您的initializeJNIVars()方法提供一个参数,该参数采用外部类的实例,然后将该实例传递给参数并在调用时使用它GetMethodID(...)。请注意,您必须将参数作为OuterClassName.this.

于 2012-10-03T14:57:51.580 回答
0

您得到的异常的描述是:

如果应用程序尝试调用类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出该异常。

通常,这个错误会被编译器捕获;如果类的定义发生了不兼容的更改,则此错误只会在运行时发生。

你的代码线程是分开的吗?当您尝试调用此方法时,是否有可能由已经死的线程加载 displayKeyStrokes 方法?

于 2012-10-03T14:35:50.893 回答