【问题标题】:how to pass java class instance as a parameter to JNI method?如何将java类实例作为参数传递给JNI方法?
【发布时间】:2026-02-10 19:55:01
【问题描述】:

我想将 java 类对象传递给 JNI 方法, 我想在 JNI 方法中调用几个方法,如下所示。

有人有下面这样的例子吗?

class JavaClassParameter{
    void javaMethodTobeCalledInJNI(){
        ...java source...
    }
}

class MainJavaClass{
    void somemethod(){
        JavaClassParameter object = new JavaClassParameter();
        JNIMethod(object);
    }

    native void JNIMethod(JavaClassParameter object);
}


// C++ code
void JNIMethod(object){
    object->javaMethodTobeCalledInJNI();
}

【问题讨论】:

  • 如果你想将一个类对象传递给一个 JNI 方法,你可以像传递任何其他对象一样传递它。上面的代码似乎是传递类的实例而不是类,所以我不确定这与您的问题有何关系。

标签: android-ndk


【解决方案1】:

你的方法声明:

class MainJavaClass {
    native void JNIMethod(JavaClassParameter object);
}

表示javah 应生成如下前向声明:

JNIEXPORT void JNICALL Java_MainJavaClass_JNIMethod(JNIEnv* env, jobject mainJavaClass);

在实施过程中,您需要做一些事情:

查找 JavaClassParameter

使用FindClass,它接受一个字符串名称:

jclass cls = env->FindClass("JavaClassParameter");

查找 javaMethodTobeCalledInJNI()

使用GetMethodID,它接受要检查的类、方法的字符串名称及其签名。由于这是一个没有参数的 void 函数,它的signature 就是()V

jmethodID method = env->GetMethodID(cls, "javaMethodTobeCalledInJNI", "()V");

调用 javaMethodTobeCalledInJNI()

使用 CallVoidMethod,它接受对象实例、方法 ID 和任何参数(在这种情况下没有参数):

env->CallVoidMethod(mainJavaClass, method);

您应该在每一步之后检查 NULL 结果;如果你从一个 JNI 函数返回一个 NULL 并将它传递给另一个,你通常会导致 JVM 崩溃

【讨论】:

  • 如果 javaMethodTobeCalledInJNI() 是绑定到 JavaClassParameter 类的静态方法,这可能会起作用。在这种情况下,它不能使用实例字段变量。该问题特别指出对象将作为实例参数传递给 JNIMethod。否则无法使用实例字段。由于 JNIMethod 是 mainJavaClass 的方法,因此 Java_MainJavaClass_JNIMethod 似乎需要三个参数:env、mainJavaClass 隐式参数和显式作业对象 JavaClassParameter_instanceObj。没有?
  • 同样在这里,您使用位于 JavaClassParameter 类下的 javaMethodTobeCalledInJNI 定义方法 ID,但您使用 mainJavaClass 的实例调用它。我不明白。
最近更新 更多