JNI函数签名

# JNI函数签名

在 Native 层调用 Java 层函数时,我们需要在根据 Java 层的函数来确定需要调用的函数的名字和签名。

例如在 Java 层定义的函数如下:

public void onSuccess(String msg) {
    ....
}

下面是 JNI 层调用 onSuccess 函数的代码

extern "C"
JNIEXPORT void JNICALL
Java_com_example_lib_JniThreadDemo_callJavaMethodOnCPPMainThread(JNIEnv *env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    //确定需要调用的函数
    jmethodID jmethod = env->GetMethodID(jclz, "onSuccess", "(Ljava/lang/String;)V");
    char *msg = "Msg From C++ Thread";
    jstring jmsg = env->NewStringUTF(msg);
    //调用 Java 层函数
    env->CallVoidMethod(instance, jmethod, jmsg);
    env->DeleteLocalRef(jmsg);
}

我们在上面的代码中,可以知道,调用 Java 函数需要确定的几点:

  • 函数的名字: "onSuccess"
  • 函数的签名: "(Ljava/lang/String;)V"

这样就可以调用了。

那么函数的签名需要怎么确定呢?

## 方式一 通过 javap -s 获取

我们编译好对应的 .java 文件,然后 cd 到 .class 字节码文件下,执行以下命令即可知道对应的函数签名:

JNI函数签名_第1张图片
函数签名

## 方式二 通过查看对应的函数表获取

签名方法参数类型对应表:

JNI函数签名_第2张图片
函数签名对应表

Ljava/lang/String 表示参数为 String 类型
V 表示返回值为 void

(Ljava/lang/String;)V

## 下面来练习几个方法的签名

public Animal search(int age,String name){return null;}

方法的签名:(ILjava/lang/String;)Lcom/example/lib/Animal;

public boolean compare(Animal animal1,Animal animal2){return false;}

方法的签名:(Lcom/example/lib/Animal;Lcom/example/lib/Animal;)Z

public boolean compare(int arr[],Animal[] animals){return false;}

方法的签名:([I[Lcom/example/lib/Animal;)Z

## 总结

  • 如果引用数据类的签名需要以 L 打头,并以 ; 结束
  • 基本数据类型直接填写即可
  • 如果是数组类型,需要以[打头,如果数组元素的类型引用数据类型,则需要以 L 打头,并以 ; 结束。

项目地址:
https://github.com/liaowjcoder/Jni4Android

记录于 2018年11月10日 双十一前夕

你可能感兴趣的:(JNI函数签名)