NDK java的對映

llj0201發表於2015-02-12

java呼叫c/c++過程

1. 已採用ndk編譯出c/c++庫(c_libname.a/ c_libname so),根據c_libname.h編寫對應的java類;
2. 根據native java類,編譯出對應的cpp檔案頭;如下面例子:
    a) 使用Java工具Javah可以很容易地建立它而不用手動去建立。你對Java的class檔案使用javah命令,就會為你生成一個對應的C/C++標頭檔案。
    b) 設定好javah的環境變數,見2.1_3,開啟控制檯,輸入 cd /d {android_project_path};
    輸入javah -classpath .\src –jni {package_name}.{java_class_name};
    將生成jni標頭檔案名為{package_name}_{java_class_name}.h 到控制檯的當前顯示路徑下。
    javac命令:javac {java_file_path}\{java_class_name}.java,編譯出*.classes
    javah命令:javah -classpath {android_project_path}\bin\classes -jni {package_name}.{java_class_name};
3. 根據生成的jni.h,實現相應的jni介面即可;
4. 接著就是library的編譯了,將其編譯為*.so動態庫;
5. 最後Java中呼叫system.load 動態庫後,並使用相應的native java類即可完成對c/c++呼叫。
    a) 生成的jni對應的C/C++實現等,這裡稱之為本地檔案/方法/型別;java類函式返回值和引數型別根據等價約定對映到本地C/C++型別,如表2-1所示:
注意:所有的本地方法的第一個引數都是指向JNIEnv結構的。這個結構是用來呼叫JNI函式的。第二個引數jclass的意義,要看方法是不是靜態的(static)或者例項(Instance)的。前者,jclass代表一個類物件的引用,而後者是被呼叫的方法所屬物件的引用。

表 2‑1 JNI型別對映

Java型別

本地型別(jni)

描述

boolean

jboolean

C/C++8位整型

byte

jbyte

C/C++帶符號的8位整型

char

jchar

C/C++無符號的16位整型

short

jshort

C/C++帶符號的16位整型

int

jint

C/C++帶符號的32位整型

long

jlong

C/C++帶符號的64位整型e

float

jfloat

C/C++32位浮點型

double

jdouble

C/C++64位浮點型

Object

jobject

任何Java物件,或者沒有對應java型別的物件

Class

jclass

Class物件

String

jstring

字串物件

Object[]

jobjectArray

任何物件的陣列

boolean[]

jbooleanArray

布林型陣列

byte[]

jbyteArray

位元型陣列

char[]

jcharArray

字元型陣列

short[]

jshortArray

短整型陣列

int[]

jintArray

整型陣列

long[]

jlongArray

長整型陣列

float[]

jfloatArray

浮點型陣列

double[]

jdoubleArray

雙浮點型陣列

       b)  JNI通過JNIEnv提供的操作Java陣列的功能。它提供了兩個函式:一個是操作java的簡單型陣列的,另一個是操作物件型別陣列的。

          b1.簡單型別的陣列,使用GetXXXArrayElements函式(2-2)XXX代表了陣列的型別

表 2‑2 JNI陣列存取函式

函式

Java陣列型別

本地型別

GetBooleanArrayElements

jbooleanArray

jboolean

GetByteArrayElements

jbyteArray

jbyte

GetCharArrayElements

jcharArray

jchar

GetShortArrayElements

jshortArray

jshort

GetIntArrayElements

jintArray

jint

GetLongArrayElements

jlongArray

jlong

GetFloatArrayElements

jfloatArray

jfloat

GetDoubleArrayElements

jdoubleArray

jdouble

          b2.操作物件型別,JNI通過ID識別域和方法,一個域或方法的ID是任何處理域和方法的函式的必須引數。

          表2-3列出了用以得到靜態(static)和例項(instance)的域與方法的JNI函式。每個函式接受(作為引數)域或方法的類,它們的名稱,符號和它們對應返回的jfieldIDjmethodID

表 2‑3 域和方法的函式

函式

描述

GetFieldID

得到一個例項的域的ID

GetStaticFieldID

得到一個靜態的域的ID

GetMethodID

得到一個例項的方法的ID

GetStaticMethodID

得到一個靜態方法的ID

      如果你有了一個類的例項,它就可以通過方法GetObjectClass得到,或者如果你沒有這個類的例項,可以通過FindClass得到。符號是從域的型別或者方法的引數,返回值得到字串,如表2-4所示。

表 2‑4 確定域和方法的符號

Java 型別

符號

boolean

Z

byte

B

char

C

short

S

int

I

long

L

float

F

double

D

void

V

objects物件

Lfully-qualified-class-name;L類名

Arrays陣列

[array-type [陣列型別

methods方法

(argument-types)return-type(引數型別)返回型別


相關文章