Android系統JNI使用(JAVA呼叫C語言介面)一
目錄
第一篇: Android系統JNI使用(JAVA呼叫C語言介面)一
什麼是JNI
JNI是Java Native Interface的縮寫,它提供了若干的API實現了Java和其他語言的通訊主要是C/C++。
從Java1.1開始,JNI標準成為java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行互動。JNI一開始是為了本地已編語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他程式語言,只要呼叫約定受支援就可以了。
使用java與本地已編譯的程式碼互動,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的。
例如,使用一些舊的庫,與硬體、作業系統進行互動,或者為了提高程式的效能。JNI標準至少要保證原生代碼能工作在任何Java 虛擬機器環境。
JNI的演化
JDK1.0包含了一個本地方法介面,它允許JAVA程式呼叫C/C++寫的程式,許多第三方的程式和JAVA類庫。如:java.lang,java.io,java.net等都依賴於本地方法來訪問底層系統環境的特徵。
不幸的是,JDK1.0中的本地方法有兩個主要問題:
1、本地方法想訪問C中的結構(structures)一樣訪問物件中的欄位。儘管如此,JVM規範並沒有定義物件怎麼樣在記憶體中實現。如果一個給定的JVM實現在佈局物件時,和本地方法假設的不一樣,那你就不得不重新編寫本地方法庫。
2、因為本地方法可以保持對JVM中物件的直接指標,所以,JDK1.0中的本地方法採用了一種保守的GC策略。
JNI的誕生就是為了解決這兩個問題,它可以被所有平臺下的JVM支援:
(1)每一個JVM實現方案可以支援大量的原生代碼。
(2)開發工具作者不必處理不同的本地方法介面。
(3)原生代碼可以執行在不同的JVM上面。
JDK1.1中第一次支援JNI,但是,JDK1.1仍在使用老風格的原生代碼來實現JAVA的API。這種情況在JDK1.2下被徹底改變成符合標準的寫法。
如何使用JNI
呼叫順序:
- 編寫帶有native宣告的方法的java類
- 編譯所編寫的java類
- 使用javah + java類名生成副檔名為h的標頭檔案
- 將C/C++編寫的檔案生成動態連線庫
Java基本資料型別與C語言基本資料型別的對應
Java Type | JNI Type | C Type | 描述 |
---|---|---|---|
boolean | jboolean | unsigned char | unsigned 8 bits |
byte | jbyte | signed char | signed 8 bits |
char | jchar | unsigned short | unsigned 16 bits |
short | jshort | short | signed 16 bits |
int | jint | long | signed 32 bits |
long | jlong | _int64 | signed 64 bits |
float | jfloa | float | 32 bits |
double | jdouble | double | 64 bits |
通過原始碼學習,讓我們直觀的看下原始碼中是怎麼定義的:
libnativehelper/include_jni/jni.h

image.png
Java物件型別
java物件對映到c++中:

所有的_j開頭的類,都是繼承於_jobject,這也是Java語言的特別,所有的類都是Object的子類,這些類就是和Java中的類一一對應,只不過名字稍有不同而已。

image.png