全誌A33開發板的安卓控制LED-2-JNI基礎
雖然您可以完全使用Java編寫應用程序,但有些情況下Java本身並不能滿足您的應用程序的需求。當應用程序不能完全用Java編寫時,程序員使用JNI編寫Java本機方法來處理這些情況。
以下示例說明何時需要使用Java本機方法:
標準Java類庫不支持應用程序所需的與平臺相關的功能。
您已經有一個用另一種語言編寫的庫,並希望通過JNI使其可以訪問Java代碼。
您希望在較低級別的語言(如匯編語言)中實現一小部分時間關鍵代碼。
來源:https://docs.oracle.com/javase/1.5.0/docs/guide/jni/
開發平臺
芯靈思SinlinxA33開發板
淘寶店鋪: https://sinlinx.taobao.com/
嵌入式linux 開發板交流 QQ:641395230
了解JNI函數
JNI函數就是在native層定義的本地函數,對應於在java層使用native關鍵字聲明的方法的。直白的說,就是在Java層聲明,C/C++語言實現的。當然,這個函數並不一般,它會通過JNI某種機制與Java層的方法進行關聯,使得Java層代碼可以很方便的調用它。
jni函數的語法和調用規則
- 將java語言的數據類型轉換成底層語言調用規則
將java語言的方法調用轉換成底層語言函數或方法
jni數據類型的轉化
jni在java和C之間建立連接,因此jni首先要統一兩者的數據類型
Java Type | 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 | N/A |
The following definition is provided for convenience.
define JNI_FALSE 0 #define JNI_TRUE 1
The jsize integer type is used to describe cardinal indices and sizes:
typedef jint jsize;
- java中可以直接調用底層語言的函數,jni規定了java調用底層語言的方法簽名
- java中有重載概念,所以java方法轉換成簽名,簽名再轉化為函數
Type Signature | Java Type | |
---|---|---|
Z | boolean | |
B | byte | |
C | char | |
S | short | |
I | int | |
J | long | |
F | float | |
D | double | |
L | fully-qualified-class | |
[ type | type[] |
For example, the Java method:
long f (int n, String s, int[] arr);
has the following type signature:
(ILjava/lang/String;[I)J
jni機制實現
native 聲明的函數可以不實現
class Cls {
native double f(int i, String s); // 聲明為本地方法
static {
System.loadLibrary(“庫名”); // 通過靜態初始化語句塊來加載動態庫
}
}
程序實現測試java代碼
javah -jni Hello
生成Hello .h
打開Hello .h 文件裏面已經寫好C函數的名字
C代碼
將C文件制做成共享庫.so,註意指定jni.h和jni_md.h文件路徑
gcc -shared -fPIC hello.c -o libhello.so -I /usr/java/jdk1.6.0_45/include/ -I /usr/java/jdk1.6.0_45/include/linux/
java Hello
運行程序
實驗現象
全誌A33開發板的安卓控制LED-2-JNI基礎