JNI完全指南

https://www.jianshu.com/nb/7649528

 

前言

本系列博客可作爲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



作者:陳小默
鏈接:https://www.jianshu.com/p/41585ea8a875
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章