Open Harmony 之 NAPI

前言

此文代碼版本為 code-v3.1-Beta。

2022/05/22 更新:oh 官方提供了一個插件用來一鍵生成 NAPI 框架代碼、業(yè)務(wù)代碼框架、GN 文件等。因此你也許沒有必要看本文。

https://gitee.com/openharmony/napi_generator#https://gitee.com/openharmony/napi_generator/blob/master/docs/INSTRUCTION_ZH.md
“本文主要介紹NAPI框架代碼生成工具,它可以根據(jù)用戶指定路徑下的ts(typescript)接口文件一鍵生成NAPI框架代碼、業(yè)務(wù)代碼框架、GN文件等。在開發(fā)JS應(yīng)用與NAPI間接口時,底層框架開發(fā)者無需關(guān)注Nodejs語法、C++與JS之間的數(shù)據(jù)類型轉(zhuǎn)換等上層應(yīng)用轉(zhuǎn)換邏輯,只關(guān)注底層業(yè)務(wù)邏輯即可,專業(yè)的人做專業(yè)的事,從而可以大大提高開發(fā)效率?!?/p>

NAPI 是什么

類似于 Android 中使用的 JNI,OH 中的 N-API 定義了的由 JS/ETS 語言編寫的代碼編繹出的字節(jié)碼和 native 代碼(使用 C/C++ 編寫)交互的方式,由 Node.js N-API 框架擴展而來。
簡單來說,OH 系統(tǒng)中的 NAPI 定義了 JS 代碼和 C++ 代碼的交互方式。

JNI:Java Native Interface;
N-API:Native Application Programming Interface;


NAPI 作用

Android 中使用的 JNI(Java Native Interface):定義了由 Java 或 Kotlin 語言編寫的代碼編譯出的字節(jié)碼和 native 代碼(使用 C/C++ 編寫)交互的方式。

NAPI 設(shè)計思想

1. 方舟編譯器(ArkCompiler)將 JS 代碼編繹成 abc 文件,并執(zhí)行

方舟編譯器(ArkCompiler)中的 ArkCompiler JS Runtime 模塊中的 JS 編譯工具鏈會將 JS 代碼轉(zhuǎn)換成方舟字節(jié)碼即 abc 文件。然后方舟編譯器中的 JS Runtime 會直接運動字節(jié)碼文件,實現(xiàn)對應(yīng)的語義邏輯。其中的 JS-NAPI 模塊將實現(xiàn) JSNAPI 接口和 C++ 的交互。


JS code 通過方舟編譯器中的 JS Runtime 轉(zhuǎn)換成 NAPI code
2. ArkCompiler 中的 JS-NAPI 模塊調(diào)用 Native 代碼注冊的 JS 接口實現(xiàn)代碼(callback method handle)
JS 方法調(diào)用 C++ 方法的流程
3. Native 代碼以 property 的形式注冊 callback method handle, 并且在 callback method 中有一個參數(shù)用于存放 JS 方法傳入的參數(shù)值

如一個 js 對象對應(yīng)的 native 對象 object,native 代碼將把 object 中的方法、變量、常量構(gòu)成 [key:methodname,value:callback method handle] 的 property 形式注冊。


Native 代碼通過 property 的形式注冊 method callback handle

如:JS 的 call 接口 @ohos.telephony.call.d.ts 中對應(yīng)的方法 dial()、變量 callstate、常量 CALL_STATE_IDLE,native 代碼將為其注冊 call 的 properties:["dial",callback method]、["callstate",getter/setter callback method]、["CALL_STATE_IDLE", callback value]


js object 方法對應(yīng)的 native callback
4. native 代碼調(diào)用 napi 創(chuàng)建 JS 的 Promise,當(dāng) callback method 執(zhí)行完成后,通過 napi 調(diào)用 Promise.resolve(value) 方法向 JS 代碼返回結(jié)果。

NAPI 數(shù)據(jù)類型和封裝函數(shù)

napi 數(shù)據(jù)類型作為 js 數(shù)據(jù)類型和 c++ 數(shù)據(jù)類型之間的橋梁,可以和 ArkComplier 中翻譯的 js 數(shù)據(jù)類型,及 c++ 數(shù)據(jù)類型相互轉(zhuǎn)換。napi 框架提供方法實現(xiàn)它們之間的互相轉(zhuǎn)換。


napi 提供數(shù)據(jù)類型的轉(zhuǎn)換

可參考 Node.js v8.x 中文文檔 ,oh 中的具體實現(xiàn)在 native_api.cpp。

其中基本的數(shù)據(jù)類型,如 :

  • napi_env 對應(yīng) NativeEngine 在 oh 中指 ArkComplier 中 JSNAPI 的相關(guān)上下文環(huán)境,任何 napi 數(shù)據(jù)類型和 js 數(shù)據(jù)類型的轉(zhuǎn)換都需要用到它。
  • napi_value 對應(yīng) NativeValue 在 oh 中指所有 ArkComplier 可識別的 js 數(shù)據(jù)類型,它有子類 ArkNativeNumber、ArkNativeString、ArkNativeFunction 等,對應(yīng) js 中的 number、string、function 等數(shù)據(jù)類型。
  • napi_callback_info 對應(yīng) NativeCallbackInfo ,指注冊 callback handle 時用來存放 js 傳入?yún)?shù)信息的數(shù)據(jù)類型。它是一個 struct。
  • napi_property_descriptor 是用來存放單個 property 的數(shù)據(jù)類型。
  • napi_callback 對應(yīng) NativeCallback,即前面的 callback handle,native 代碼將其注冊為對應(yīng) js 接口的回調(diào)函數(shù)。
typedef napi_value (*napi_callback)(napi_env env, napi_callback_info info)

其中基本的轉(zhuǎn)換函數(shù),如:

  • 將 c++ 轉(zhuǎn)換成 napi 的函數(shù): napi_create_string_utf8 等;
  • 將 napi 轉(zhuǎn)換成 c++ 的函數(shù): napi_get_value_string_utf8 等;
  • 創(chuàng)建編譯器中的 js 對象: napi_create_function 等;
  • 回調(diào) js 函數(shù):napi_call_function

使用 NAPI

使用 napi 時只要完成以下幾個步驟:

1. 向系統(tǒng)注冊我們要實現(xiàn)的 js 接口對象(在 oh 中指要新增的子系統(tǒng))

分為以下幾步:
首先:

BUILD.gn 中聲明 js 接口對象 object :ohos_shared_libarary("object")

其次:

通過 napi_module_register 注冊 module

最后:

定義 napi_module ,注冊 module 中 object 的 properties
2. 注冊我們要提供的子系統(tǒng)接口的 properties

首先,定義所有的常量、變量、方法 property:

DECLARE_NAPI_FUNCTION("methodName", NativeMethod);

然后,注冊所有 properties

通過 napi_define_properties 注冊 object 的 properties
3. 實現(xiàn)所有 property 中的回調(diào)方法:
從 napi_callback_info 中取出 JS 調(diào)用時傳入的所有參數(shù),
并調(diào)用 napi 方法將其從 napi 數(shù)據(jù)類型的值 napi_value 轉(zhuǎn)換成 native 數(shù)據(jù)類型的值

參考

Node.js v8.x 中文文檔
oh 官網(wǎng):napi

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容