本章讨论JNI如何将Java类型映射到本机C类型。
本章包括以下主题:
目录
原始类型
下表描述了Java基元类型及其与机器相关的本机等效项。
Java Type(Java类型) | Native Type | Description |
---|---|---|
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 | not applicable |
#define JNI_FALSE 0提供以下定义是为了方便起见。
#define JNI_TRUE 1
jsize
整数类型用于描述基数索引和大小:
typedef jint jsize;
参考类型
JNI包含许多与不同类型的Java对象相对应的引用类型。 JNI引用类型按以下层次结构组织:
- 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引用类型都定义为与jobject相同。 例如:
typedef jobject jclass;
在C ++中,JNI引入了一组虚拟类来强制执行子类型关系。 例如:
class _jobject {};
class _jclass:public _jobject {};
// ...
typedef _jobject * jobject;
typedef _jclass * jclass;
字段和方法ID
方法和字段ID是常规C指针类型:
struct _jfieldID; / *不透明结构* /
typedef struct _jfieldID * jfieldID; / *字段ID * /
struct _jmethodID; / *不透明结构* /
typedef struct _jmethodID * jmethodID; / *方法ID * /
价值类型
jvalue
union类型用作参数数组中的元素类型。 声明如下:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
输入签名
JNI使用Java VM的类型签名表示。 下表显示了这些类型签名。
Type Signature | Java Type |
---|---|
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 |
例如,java的方法:
long f (int n, String s, int[] arr);
long f(int n,String s,int [] arr);
具有以下类型签名:
(ILjava/lang/String;[I)J
修改了UTF-8字符串
JNI使用修改的UTF-8字符串来表示各种字符串类型。 修改后的UTF-8字符串与Java VM使用的字符串相同。 对已修改的UTF-8字符串进行编码,以便每个字符仅使用一个字节表示仅包含非空ASCII字符的字符序列,但可以表示所有Unicode字符。
范围\ u0001到\ u007F中的所有字符都由单个字节表示,如下所示:
0 xxxxxxx
字节中的七位数据给出了所表示字符的值。
空字符( '\u0000'
)和'\u0080'
到'\u07FF'
范围内'\u0080'
'\u07FF'
由一对字节x和y表示:
- x:
110 xxxxx
- y:
10 yyyyyy
字节表示具有值((x& 0x1f
)<< 6
)+(y和0x3f
)的字符。
'\u0800'
到'\uFFFF'
范围内'\u0800'
字符由3个字节x,y和z表示:
- x:
1110 xxxx
- y:
10 yyyyyy
- z:
10 zzzzzz
具有值((x& 0xf
)<< 12
)+((y& 0x3f
)<< 6
)+(z& 0x3f
)的字符由字节表示。
代码点高于U + FFFF的字符 (所谓的补充字符 )通过分别编码其UTF-16表示的两个代理代码单元来表示。 每个代理代码单元由三个字节表示。 这意味着,补充字符由六个字节u , v , w , x , y和z表示 :
- 你:
11101101
- v:
1010 vvvv
- w:
10 wwwwww
- x:
11101101
- y:
1011 yyyy
- z:
10 zzzzzz
值为0x10000 +((v&0x0f)<< 16)+((w&0x3f)<< 10)+(y&0x0f)<< 6)+(z&0x3f)的字符由六个字节表示。
多字节字符的字节以big-endian(高字节优先)顺序存储在class
文件中。
此格式与标准UTF-8格式有两点不同。 首先,使用双字节格式而不是单字节格式对空字符(char)0
进行编码。 这意味着修改后的UTF-8字符串永远不会嵌入空值。 其次,仅使用标准UTF-8的单字节,双字节和三字节格式。 Java VM无法识别标准UTF-8的四字节格式; 它使用自己的两倍三字节格式代替。