目錄
第一章 介紹
第二章 設計機制
第三章 JNI類型和數據結構
第四章 JNI函數(1)
第四章 JNI函數(2)
第四章 JNI函數(3)
第四章 JNI函數(4)
第五章 Invocation API
第三章 JNI類型和數據結構
本章主要討論JNI如何映射Java和C之間數據類型。
3.1 基本類型
Java類型 | 本地類型 | 描述 | c類型 |
---|---|---|---|
int | jint | signed 32 bits | 根據平臺不同 |
long | jlong | signed 64 bits | 根據平臺不同 |
byte | jbyte | signed 8 bits | 根據平臺不同 |
char | jchar | unsigned 16 bits | typedef unsigned short |
short | jshort | singed 16 bits | typedef short |
boolean | jboolean | unsigned 8 bits | typedef unsigned char |
float | jfloat | 32 bits | typedef float |
double | jdouble | 64 bits | typedef double |
void | void | N/A | N/A |
<u>以下為個人理解部分:</u>
從JVM的源碼來看,JNI在不同平臺上映射的類型是區別的,其中主要針對的是 jint
jlong
jbyte
:
源碼如下:
#ifdef TARGET_ARCH_x86
# include "jni_x86.h"
#endif
#ifdef TARGET_ARCH_sparc
# include "jni_sparc.h"
#endif
#ifdef TARGET_ARCH_zero
# include "jni_zero.h"
#endif
#ifdef TARGET_ARCH_arm
# include "jni_arm.h"
#endif
#ifdef TARGET_ARCH_ppc
# include "jni_ppc.h"
#endif
例如在x86架構下的定義:
#define JNICALL
typedef int jint;
#ifdef _LP64
typedef long jlong;
#else
typedef long long jlong;
#endif
#else
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef int jint;
typedef __int64 jlong;
#endif
typedef signed char jbyte;
<u>以上為個人理解部分。</u>
為了方便還定義了true、false:
#define JNI_FALSE 0
#define JNI_TRUE 1
還定義了整數型 jsize
來表示大?。?/p>
typedef jint jsize;
3.2 引用類型
jni類型 | Java類型 |
---|---|
jobject | Object |
|- jclass | java.lang.Class |
|- jstring | java.lang.String |
|- jarray | array |
|----jobjectArray | Object[] |
|----jbooleanArray | boolean[] |
|----jbyteArray | byte[] |
|----jcharArray | char[] |
|----jshortArray | short[] |
|----jintArray | int[] |
|---- jlongArray | long[] |
|---- jfloatArray | float[] |
|---- jdoubleArray | double[] |
|- jthrowable | java.lang.Throwable |
在C的實現中,所有的JNI引用類型都定義和 jobject
一樣的,例如:
typedef jobject jclass;
而在C++的實現中,所有的JNI引用類型都被定義為一個空的類,例如:
class _jobject {};
class _jclass : public _jobject {};
// ...
typedef _jobject *jobject;
typedef _jclass *jclass;
3.3 成員域和成員方法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類型
jvalue類型是一個c的union類型,定義如下:
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虛擬機的簽名類型描述符,如下:
類型簽名 | 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 |
例如有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
3.6 MUTF-8字符串
JNI使用Modified UTF-8(MUTF-8)字符串來表示各種字符串類型。Java虛擬機里面也同樣使用MUTF-8字符串。
MUTF-8和標準的UTF-8字符串是由區別的。具體的區別可以查看wiki說明。