上一篇:?02-設計概述
????????本章討論 JNI 如何將 Java 類型映射為本地 C 類型。
3.1?原始類型
????????下表描述了 Java 原始類型及其與機器相關的本地等價類型。
????????為方便起見,定義如下:
#define JNI_FALSE 0
#define JNI_TRUE 1
????????jsize 整數類型用于描述基數索引和大小:
typedef jint jsize;
3.2 引用類型
????????JNI 包括許多與Java 對象相對應的、不同類型的引用類型。JNI 引用類型按以下層次結構組織:
jobjectjclass (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;
3.3?字段和方法 ID
????????方法和字段 ID 是常規的 C 指針類型:
struct _jfieldID; /* opaque structure */
typedef struct _jfieldID *jfieldID; /* field IDs */struct _jmethodID; /* opaque structure */
typedef struct _jmethodID *jmethodID; /* method IDs */
3.4 值類型
????????jvalue 聯合類型在參數數組中用作元素類型。其聲明如下:
typedef union jvalue {jboolean z;jbyte b;jchar c;jshort s;jint i;jlong j;jfloat f;jdouble d;jobject l;
} jvalue;
3.5 類型簽名
????????JNI 使用 Java VM 的類型簽名表示法。下表列出了這些類型簽名:
????????例如,Java 方法:
long f (int n, String s, int[] arr);
????????的類型特征,如下:
(ILjava/lang/String;[I)J
String的全稱類文件位于:libcore/ojluni/src/main/java/java/lang/String.java
package java.lang;
3.6?修改后的 UTF-8 字符串
????????JNI 使用修改后的 UTF-8 字符串來表示各種字符串類型。修改后的 UTF-8 字符串與 Java VM 使用的字符串相同。修改后的 UTF-8 字符串經過編碼后,只包含非空 ASCII 字符的字符序列,可使用每個字符一個字節來表示,但所有 Unicode 字符均可表示。
????????\u0001 到 \u007F 范圍內的所有字符都用一個字節表示,如下所示:
0xxxxxxx
????????字節中的七位數據給出了所代表字符的值。
????????空字符 ( '\u0000' ) 和范圍在 '\u0080' 到 '\u07FF' 之間的字符由一對字節 x 和 y 表示:
x: 110xxxxx x: 110xxxxx
y: 10yyyyyy y: 10yyyyyy
????????字節表示值為 ((x & 0x1f ) << 6 ) + (y & 0x3f ) 的字符。
????????'\u0800' 至 '\uFFFF' 范圍內的字符由 3 個字節 x、y 和 z 表示:
x: 1110xxxx x: 1110xxxx
y: 10yyyyyy y: 10yyyyyy
z: 10zzzzzz z: 10zzzzzz
????????值為 ((x & 0xf ) << 12 ) + ((y & 0x3f ) << 6 ) + (z & 0x3f ) 的字符用字節表示。
????????碼位在 U+FFFF 以上的字符(即所謂的補充字符)通過對其 UTF-16 表示形式的兩個代理碼單元進行單獨編碼來表示。每個代理編碼單元由三個字節表示。也就是說,補充字符由 u、v、w、x、y 和 z 六個字節表示:
u: 11101101 u: 11101101
v: 1010vvvv v: 1010vvvv
w: 10wwwwww w: 10wwwwww
x: 11101101 x: 11101101
y: 1011yyyy y: 1011yyyy
z: 10zzzzzz z: 10zzzzzz
????????數值為 0x10000+((v&0x0f)<<16)+((w&0x3f)<<10)+(y&0x0f)<<6)+(z&0x3f) 的字符由這六個字節表示。
????????多字節字符的字節在 class 文件中按大字節(高字節在前)順序存儲。
????????這種格式與標準 UTF-8 格式有兩點不同。首先,空字符 (char)0 使用雙字節格式編碼,而不是單字節格式。這意味著修改后的 UTF-8 字符串永遠不會嵌入空字符。其次,只使用標準 UTF-8 的一字節、二字節和三字節格式。Java 虛擬機不識別標準 UTF-8 的四字節格式,而是使用自己的兩倍三字節格式。
????????有關標準 UTF-8 格式的更多信息,請參見《Unicode Encoding Forms of The Unicode Standard》4.0 版第 3.9 節。
下一篇: