前言
何老師又來送福利啦,做NDK開發的朋友有福啦~
首先感謝一下醫生,若是沒有你催命般的催稿,還真就沒有這篇了。作為催我的代價,請客可樂是沒跑的了:)
NDK Mapping
的主要工作就是完成 class 從 JVM 層到 JNI 層的映射。通常情況下,當我們進行 JNI 開發時,無可避免的要進行類的傳遞操作,而 JNI 提供的 API 卻讓代碼簡單不起來,大量的容易出錯的體力勞動也是這麼來的。來看看以下的代碼:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAjM2EzLcd3LcJzLcJzdllmVldWYtl2PnVGcq5yZrFHe1J2Y3I3dvw1MxYzNwkTMtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.jpeg)
大家都能讀懂的吧?就是調用一下 JVM 層
DemoInc
類的
getId
方法,卻花費了如此多的代碼。那麼再設想一下如果是操作
List
,
Map
或是其他複雜類型呢?幾十行代碼都不一定做得下來。而這正是
NDK Mapping
誕生的初衷,即幫助開發者完成類的映射。
來個具體的執行個體看看效果吧,要特别說明的是,
NDK Mapping
接受的映射類檔案必須是
Kotlin
的
data class
,原因很簡單,一方面是因為這樣的 class 足夠簡單,友善解析,另一方面就是我懶。看看這樣一個 class:
想一下用 JNI 來操作這樣的類需要多少代碼,你是否還記得
List
的
Add
方法簽名是什麼樣的?當然現在你說不記得也沒關系了,在
NDK Mapping
的幫助下,開發者不需要記憶任何與類操作有關的東西。
簡單的看一下
NDK Mapping
的指令參數,當直接輸入
ndkmapping
指令時,即可看到如下的參數提示:
-l
表示目智語言,目前可以生成 C++ 和 Pascal 的類映射,
-b
表示生成 Makefile,
-m
表示數組傳參時,數組的最大下标,
-o
表示生成的檔案輸出的位置,若是沒有該目錄,則會建立一個。當然在最後還得再跟上
Kotlin Class
的所在目錄,
ndkmapping
會自動的映射所有的
class
檔案。
完整的指令如下:
是的,你沒有看錯,生成的代碼是可以直接編譯的,并不需要再經過任何的修改,此時在 JNI 層的代碼内,就有了一個與 JVM 層形态完全一樣的類,可以直接操作。
而最關鍵的,是生成了兩個方法:
顧名思議也很清晰了,一個是将 jobject 所對應的類,翻譯成 JNI 的類,而另一個,是将 JNI 的類翻譯回 jobject。有了這兩個方法,就可以實作映射。而在實際開發中,基本上也隻需要調用這兩個方法,其他的一切操作,都是與平台和語言本身相關的了。
下面是映射關系表,參考這個表,可以知道在生成代碼時的規則。
Kotlin | C++ | Pascal | JNI |
---|---|---|---|
Int | int | Integer | jint |
Byte | unsigned char | Byte | jbyte |
Short | short | ShortInt | jshort |
Long | long long | Int64 | jlong |
Float | float | Extended | jfloat |
Double | double | Double | jdouble |
Boolean | bool | Boolean | jboolean |
Char | char | Char | jchar |
String | string | String | jstring |
List | list | FPGList | jobject |
Map | map | FPGMap | jobject |
Set | set | FPGList | jobject |
Array | [array] | [array] | jobjectArray |
對于一份生成好的代碼來說,進行驗證是有必要的。
NDK Mapping
同樣也提供了驗證的能力。使用
ndktester
即可。
參數基本上都與
ndkmapping
類似,要額外選擇驗證代碼的語言,和原始生成的代碼語言,另外還需要用于 JVM 驗證的包名,如果你需要在編譯驗證庫後複制到其他項目中,可以使用
-c
參數。
指令的樣本如下:
此時就會生成用于 Kotlin 驗證的代碼,直接引入到一個項目即可。
保險起見,另外還提供了一份較為複雜的類的映射樣例代碼,可以從項目的 README 内找到下載下傳位址。
章魚貓位址:rarnu/ndkmapping