从本机库回调到JNI接口

时间:2019-06-27 04:24:03

标签: java android c java-native-interface

如何从本机库调用函数到JNI接口,如何从JNI接口调用函数到JAVA?那可能吗?我该怎么办?

下面是JNI接口(假设)

JNIEXPORT void JNICALL Java_com_example_test_mode_calltoJava(
        JNIEnv *env,
        jobject /* this */) {

/*Call to Java Function */
}

下面是C库函数(假设)

void test(int a,int b){
           Call to JNI Interface
          //Java_com_example_test_mode_calltoJava(a,b)
}

注意:我的框架是这样的:[C库] <---> [JNI接口] <---> [JAVA],我需要在C库中注册一个回调JNI接口,然后在我的C库中发生适当的事件时,已注册的回调应调用JAVA函数。

1 个答案:

答案 0 :(得分:0)

反之亦然。

Java_com_example_test_mode_callToJava的声明是本机C函数。因此,实际上您在某处声明了native void callToJava();并称为javac -h。您得到了此函数声明。

此函数是本地函数,可以从Java调用。

尽管如此,这里还是一个示例,该声明确切地具有从本地函数中回调Java方法的声明。

当然应该使用不同的名称。但是这里有一个实现,在本机C端看起来像是这样。在这里,我们正在回调名为test的Java方法。

JNIEXPORT void JNICALL Java_com_example_test_mode_callToJava(JNIEnv *jenv, jobject jobj) {    
      jclass cls = (*jenv)->GetObjectClass(jenv, jobj);
      jmethodID mid = (*jenv)->GetMethodID(jenv, cls, "test", "(II)V");

      jint a = 42;
      jint b = 4711;
      (*jenv)->CallVoidMethod(jenv, jobj, mid, a, b);     
}

您将像这样从Java调用它:

mode m = new mode();
m.callToJava();

别忘了声明:

native void callToJava();

因此,上面的本机C函数调用Java函数。它被称为测试。

Java方法可能如下所示:

void test(int a, int b) {
    System.out.println("a=" + a + " b=" + b);

到控制台的输出将是:

a=42 b=4711