NDK java的對映
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函式。每個函式接受(作為引數)域或方法的類,它們的名稱,符號和它們對應返回的jfieldID或jmethodID。
表 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(引數型別)返回型別 |
相關文章
- NDK 知識梳理(3) JNI 之 Java 和 JNI 資料型別對映Java資料型別
- Java 對映 自定義排序Java排序
- JNI/NDK開發指南(3):JNI資料型別及與Java資料型別的對映關係資料型別Java
- java物件關係對映ROMJava物件
- MongoDB、Java與物件關係對映MongoDBJava物件
- MongoDB、Java和物件關係對映MongoDBJava物件
- ElasticSearch中的對映Elasticsearch
- 如何使用Java泛型對映不同的值型別Java泛型型別
- Java實體對映工具MapStruct詳解JavaStruct
- 多重對映
- MyBatis(四) 對映器配置(自動對映、resultMap手動對映、引數傳遞)MyBatis
- Java實體對映工具MapStruct使用詳解JavaStruct
- Cache與主存之間的直接對映,全相聯對映和組項聯對映以及其地址變換
- 本地方法怎麼對映Java層的資料型別Java資料型別
- 解決java“錯誤:編碼GBK的不可對映字元”Java字元
- 修改對映地址
- Mybatis學習筆記(5)-高階對映之多對多對映MyBatis筆記
- 埠對映,內網網站對映外網訪問,透過80埠對映實現內網網站
- [非專業翻譯] Mapster - 對映前&對映後
- 修改 Docker 容器對映的埠Docker
- UI與實體的對映UI
- 修改docker容器的埠對映Docker
- elasticsearch的字串動態對映Elasticsearch字串
- MVC框架的對映和解耦MVC框架解耦
- iBatis中對映的疑惑BAT
- DOM對映的特殊情況
- Mybatis學習筆記(4)-高階對映之一對多對映MyBatis筆記
- Mybatis學習筆記(3)—高階對映之一對一對映MyBatis筆記
- Java使用記憶體對映實現大檔案的上傳Java記憶體
- Linux埠對映是什麼?如何進行埠對映?Linux
- JPA關係對映系列四:many-to-many 關聯對映
- Mybatis結果對映MyBatis
- VMware Fusion 埠對映
- Docker-埠對映Docker
- Nginx埠對映配置Nginx
- TypeScript 對映型別TypeScript型別
- 記憶體對映記憶體
- hibernate 元件對映元件