如何将java类实例作为参数传递给JNI方法?

how*_*eek 11 android-ndk

我想将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();
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*zek 15

你的方法声明:

class MainJavaClass {
    native void JNIMethod(JavaClassParameter object);
}
Run Code Online (Sandbox Code Playgroud)

意味着javah应该生成如下的前向声明:

JNIEXPORT void JNICALL Java_MainJavaClass_JNIMethod(JNIEnv* env, jobject mainJavaClass);
Run Code Online (Sandbox Code Playgroud)

在实现中,您有几件事要做:

找到JavaClassParameter

使用FindClass,它采用字符串名称:

jclass cls = env->FindClass("JavaClassParameter");
Run Code Online (Sandbox Code Playgroud)

查找javaMethodTobeCalledInJNI()

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

jmethodID method = env->GetMethodID(cls, "javaMethodTobeCalledInJNI", "()V");
Run Code Online (Sandbox Code Playgroud)

调用javaMethodTobeCalledInJNI()

使用CallVoidMethod,它接受对象实例,方法ID和任何参数(在本例中为none):

env->CallVoidMethod(mainJavaClass, method);
Run Code Online (Sandbox Code Playgroud)

您应该在每个步骤后检查NULL结果; 如果从一个JNI函数返回NULL并将其传递给另一个JNI函数,则通常会使JVM崩溃

  • 如果 javaMethodTobeCalledInJNI() 是绑定到 JavaClassParameter 类的静态方法,则这可能有效。在这种情况下,它不能使用实例字段变量。该问题具体指出该对象将作为实例参数传递给 JNIMethod。否则无法使用实例字段。由于 JNIMethod 是 mainJavaClass 的方法,因此 Java_MainJavaClass_JNIMethod 似乎需要三个参数:env、mainJavaClass 隐式参数和显式 jobject JavaClassParameter_instanceObj。不? (2认同)