Android Studio NDK 入门教程(3)--Java与C++之间的类型签名
来源:互联网 发布:网络黑白txt下载 编辑:程序博客网 时间:2024/05/17 16:15
概述
本文主要介绍Java与C++通信时函数的签名关系
方法签名
我们可以在生成的头文件中看到每个方法上面都有如下注释:
/* * Class: com_example_wastrel_hellojni_HelloJNI * Method: getFormCString * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getFormCString (JNIEnv *, jclass);
其中前两个注释很容易理解,第三个就是方法签名,为什么会有方法签名这种东西呢?
这是因为Java这边支持函数重载,即虽然参数不一样,但是方法名一样,那么在JNI层它们的方法名都会是一样的,那JNI也会犯迷糊了,得找哪个呢?
不过也正是因为其参数类型是不一样的,所以就出现了方法签名,利用方法签名和方法名来唯一确定一个JNI函数的调用。既然方法签名是基于参数类型的不同而形成的,首先要知道Java各数据类型对应的签名是什么,也就是所谓的类型签名。
类型签名转换表
jni.h里面定义了这样一套规则:
typedef union jvalue { jboolean z; jbyte b; jchar c; jshort s; jint i; jlong j; jfloat f; jdouble d; jobject l;} jvalue;
那么对应在JAVA中的关系如下表:
注意:上面的类后面是有一个分号的。
如何计算一个方法的类型签名
Java函数的类型签名是根据函数的参数类型以及返回类型所决定的,参数类型放在括号里面返回类型紧跟在括号外。
//native测试方法声明 public static native String getFormCString(); //三个重载方法 public static native int TypeTest(boolean a,short b,long c,char d); public static native Objects TypeTest(Date date,byte []m,HelloJNI k); public static native Long Test(Character k,Double m); //执行生成头文件命令 /* * Class: com_example_wastrel_hellojni_HelloJNI * Method: getFormCString * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getFormCString (JNIEnv *, jclass); /* * Class: com_example_wastrel_hellojni_HelloJNI * Method: TypeTest * Signature: (ZSJC)I */ JNIEXPORT jint JNICALL Java_com_example_wastrel_hellojni_HelloJNI_TypeTest__ZSJC (JNIEnv *, jclass, jboolean, jshort, jlong, jchar); /* * Class: com_example_wastrel_hellojni_HelloJNI * Method: TypeTest * Signature: (Ljava/util/Date;[BLcom/example/wastrel/hellojni/HelloJNI;)Ljava/util/Objects; */ JNIEXPORT jobject JNICALL Java_com_example_wastrel_hellojni_HelloJNI_TypeTest__Ljava_util_Date_2_3BLcom_example_wastrel_hellojni_HelloJNI_2 (JNIEnv *, jclass, jobject, jbyteArray, jobject); /* * Class: com_example_wastrel_hellojni_HelloJNI * Method: Test * Signature: (Ljava/lang/Character;Ljava/lang/Double;)Ljava/lang/Long; */ JNIEXPORT jobject JNICALL Java_com_example_wastrel_hellojni_HelloJNI_Test (JNIEnv *, jclass, jobject, jobject);
通过以上代码可以可以看出,重载的方法生成的头文件后函数名后面都追加参数的类型签名,并且‘/’被替换成了下划线‘_’,‘;’被替换成了数字‘2’;‘[’被替换成了数字‘3’。在签名中()里面表示方法的参数,紧接着的是返回类型对应的签名。可以看到String getFromCString
因为没有参数,所以()里面什么都没有,但其有一个返回参数String,String并不是Java的基础类型,String的全称是java.lang.String
,根据签名规则就是Ljava/lang/String;
,因此该方法的签名是()Ljava/lang/String
。这里需要注意,如果一个Java函数没有返回即void,那么对应的返回类型签名就是V。
其余函数有兴趣可以根据上述规则推理,我相信各位程序员的推理能力,这里就不一一讲解。
后记
方法签名是为了便于Java与native代码的相互访问,后面通过C++调用Java代码的时候,方法签名尤为重要。在传递复杂类型的时候相对较为麻烦,在实际使用中并不建议传递复杂对象。这里说一下Java方法重载,在编写native函数的时候不建议使用重载,重载的方法名称很长,辨识度也不高。更建议在java中预处理重载的调用。例如:
public class NativeFunc{ public String Func(String str){ return native_func1(str); } public String Func(int i){ return native_func2(i); } public native String native_func1(String str); public native String native_func2(int i);}
- Android Studio NDK 入门教程(3)--Java与C++之间的类型签名
- Android Studio NDK 入门教程(2)--Java与C++之间的简单数据转换与传递
- Android Studio NDK 入门教程(5)--Java对象的传递与修改
- Android Ndk中C与JAVA之间的互相调用
- Android Studio NDK 入门教程--JNI签名验证防止恶意调用
- Android Studio NDK 入门教程(6)--JNI签名验证防止恶意调用
- Android Studio NDK 入门教程(1)--来自C 语言的String
- Android Studio NDK 入门教程(1)--来自C 语言的String
- Android Studio NDK 入门教程
- android NDK java-c中的签名
- Android NDK开发之旅(3): 详解JNI数据类型与C/C++、Java之间的互调
- android NDK --java 与 C 语言之间传递数据
- Android Studio NDK 入门教程(7)--被NDK支持的C++运行库
- Android NDK中C和java之间数组的传送
- Android NDK开发之 NDK类型签名
- NDK学习笔记(2)——C与java之间的互相调用
- Android Studio NDK(C++)
- Android Studio NDK开发之一(Java调用C的方法)
- c++OTL错误汇总
- 四元数与欧拉角(Yaw、Pitch、Roll)的转换
- Qt中 QString 和int, char等的“相互”转换
- 数据库中索引的优缺点和分类
- Weex项目初始化weex-iOS集成
- Android Studio NDK 入门教程(3)--Java与C++之间的类型签名
- 使用CooCox的CoIDE打开mbed项目失败:提示 The chip:STM32F103RB information of current project has sonething wrong
- 猎豹浏览器访问webapp报HTTP405错误
- MapReduce 杂记
- 面试题29:找到数组中出现次数超过一半的数字(java)
- 【数据结构】堆、堆排序笔记
- Java基础之(三十五)输入输出<一>
- JAVA 网络编程(6) Netty TCP 示例
- Qt中QLabel的字符串连接