JNI完全指南(一)——数据类型
标签(空格分隔): JNI完全指南
版本:1
作者:陈小默
声明:禁止商业,禁止转载
前言
本系列博客可作为JNI参考文档使用,对于初学者,应当在了解了如何在特定平台上(Window、Linux、Android等)搭建JNI开发环境后再来查看。本系列博客主要参考了JNI-API文档,并以此为基础进行扩展。水平不足,如有错误,恳请批评指正。
[toc]
一、数据类型
本章内容介绍JNI如何进行Java和C的数据映射。
1.1 基本数据类型
下表中的数据为JNI基本数据类型及对应的长度
Java类型 | JNI类型 | 描述 |
---|---|---|
boolean | jboolean | unsigned 8 bits |
byte | jbyte | signed 8 bits |
char | jchar | unsigned 16 bits |
short | jshort | signed 16 bits |
int | jint | signed 32 bits |
long | jlong | signed 64 bits |
float | jfloat | 32 bits |
double | jdouble | 64 bits |
void | void | void |
为了向Java那样使用jboolean类型,以下定义了两个宏用来表示Boolean的两个值:
#define JNI_FALSE 0
#define JNI_TRUE 1
整数jsize类型用来描述尺寸等信息:
typedef jint jsize;
1.2 引用类型
JNI除了基本数据类型,还按照了Java的规范定义了若干引用类型:
- jobject
- jclass (java.lang.Class objects)
- jstring (java.lang.String objects)
- jarray (arrays)
- jobjectArray (object arrays)
- jbooleanArray (boolean arrays)
- jbyteArray (byte arrays)
- jcharArray (char arrays)
- jshortArray (short arrays)
- jintArray (int arrays)
- jlongArray (long arrays)
- jfloatArray (float arrays)
- jdoubleArray (double arrays)
- jthrowable (java.lang.Throwable objects)
如果使用的语言是C,那么在jni.h中,所有的JNI引用类型都使用如下方式声明:
typedef jobject jclass;
如果使用的语言是C++,那么在jni.h中,所有的JNI引用类型都使用如下类方式声明:
class _jobject {};
class _jclass : public _jobject {};
// ...
typedef _jobject *jobject;
typedef _jclass *jclass;
1.3 属性和方法的ID
方法和属性的ID被声明为C指针类型:
struct _jfieldID; /* opaque structure */
typedef struct _jfieldID *jfieldID; /* field IDs */
struct _jmethodID; /* opaque structure */
typedef struct _jmethodID *jmethodID; /* method IDs */
1.4 值类型
jvalue共用体类型可以保存多种类型的数据,通常用于数组,其定义如下:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
1.5 类型签名
JNI使用签名作为Java虚拟机内容的表示。下表展示了这些签名:
类型签名 | 对应的Java类型 |
---|---|
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
L全类名; | 类 |
[ type | type[] |
(参数类型签名,...)返回值类型签名 | 方法类型 |
例如,对于一个方法:
long f (int n, String s, int[] arr);
这个方法的签名为:
(ILjava/lang/String;[I)J
1.6 使用UTF-8字符串
在JNI中定义了UTF-8的字符串以匹配Java虚拟机中的字符串。UTF-8一个字符的长度不固定,而C语言中使用一个字节表示的ASCII字符。
在UTF-8中,对于单字节仍然采用ASCII码表。表示的字符的取值范围\u0001
到 \u007F
,其在内存中存储是下面这个样子:
- 0xxxxxxx
单字节有效位数为7,第一位始终为0。这里我们可以看出,对于以ASCII编码的字符串可以直接当做UTF-8字符串使用。
对于空字符其表示为\u0000
。
双字节字符在UTF-8中使用两个字节存放,且字符的开头为11 表示这个一个双字节字符。就先下面这样:
- 高位: 110xxxxx
- 低位: 10yyyyyy
对于需要三个字节表示的字符,其最高位使用111表示该字符的字节数。就像下面这样:
- 高位: 1110xxxx
- 中位: 10yyyyyy
- 低位: 10zzzzzz
下一篇:JNI完全指南(二)——类与异常
[1]ORACLE guides for JNI——Chapter 3: JNI Types and Data Structures