# 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 字节码文件下,执行以下命令即可知道对应的函数签名:

## 方式二 通过查看对应的函数表获取
签名方法参数类型对应表:

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日 双十一前夕
网友评论