JNI类型和数据结构

Posted by Haiden on April 5, 2019

一、JNI类型和数据结构

1.1 基本类型

Java 类型 Native Type 描述
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 N/A

1.2 引用类型

java类型 Jni类型
Object jobject
java.lang.Class - jclass
java.lang.String - jstring
array - jarray
Object[] —-jobjectArray
boolean[] —-jbooleanArray
byte[] —-jbyteArray
char[] —-jcharArray
short[] —-jshortArray
int[] —-jintArray
long[] —- jlongArray
float[] —- jfloatArray
double[] —- jdoubleArray
java.lang.Throwable - jthrowable

JNI 如果使用 C++ 语言编写的话,所有引用类型派生自 jobject,使用 C++ 的继承结构特性,使用相应的类型。如下所示:

1
2
3
4
5
6
class _jobject {};  
   class _jclass : public _jobject {};  
   class _jstring : public _jobject {};  
   class _jarray : public _jobject {};  
   class _jbooleanArray : public _jarray {};  
   class _jbyteArray : public _jarray {};  

1.3 字段和方法ID

字段和方法都被定义为普通的C指针类型:

1
2
3
4
5
struct _jfieldID;              /* opaque structure */ 
typedef struct _jfieldID *jfieldID;   /* field IDs */ 
 
struct _jmethodID;              /* opaque structure */ 
typedef struct _jmethodID *jmethodID; /* method IDs */ 

1.4 jvalue类型

jvalue 是一个 unio(联合)类型,在 C 语言中为了节约内存,会用联合类型变量来存储声明在联合体中的任意类型数据 。在 JNI 中将基本数据类型与引用类型定义在一个联合类型中,表示用 jvalue 定义的变量。

1
2
3
4
5
6
7
8
9
10
11
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 fully-qualified-class ; fully-qualified-class
[ type type[]
( arg-types ) ret-type method type
1
2
3
4
5
6
7
8
9
10
11
12
//例如有Java方法:
long f (int n, String s, int[] arr);

-------------------------------------
//则类型签名为:
(ILjava/lang/String;[I)J 

I 对应 int n 参数
Ljava/lang/String; 对应 String s 参数 注意包名不用点而用斜杠对应结尾用一个分号
[I 对应 int[] arr 参数
括号对应括号
J 对应返回值 long

1.6 MUTF-8字符串

JNI使用Modified UTF-8(MUTF-8)字符串来表示各种字符串类型。Java虚拟机里面也同样使用MUTF-8字符串。MUTF-8和标准UTF-8的区别有两点.

一是空字符(“\0”)在MUTF-8里被编码为两个字节: 0xC080(即1100000010000000). 它在标准UTF-8里编码为0x00. 二是SP内的字符, 首先以UTF-16的编码方式编为一个前导代理和一个后尾代理, 然后再用标准UTF-8分别编码这两个代理.