三方庫移植之NAPI開發[2]C/C++與JS的數據類型轉換
在《三方庫移植之NAPI開發[1]—Hello OpenHarmony NAPI》通過一個Hello OpenHarmony NAPI樣例講述了NPAI接口開發基礎知識。本文在其基礎上修改hellonapi.cpp文件,介紹JS類型和C/C++數據類型之間的轉換。
- 開發基于最新的OpenHarmony3.2Beta3版本及其對應SDK。標準系統開發板為潤和軟件dayu200。
筆者刻苦學習了三方庫NAPI開發的一些皮毛,將學習經驗分享如下:
演示視頻:https://ost.51cto.com/show/18126
通過本文您將熟悉,通過NAPI框架:
- 如何獲取JS傳遞過來的參數。
- 如何將JS傳遞過來的參數(NAPI框架已封裝為napi_value類型)轉換成C/C++類型值用于計算。
- 如何將C/C++類型的值轉換成JS類型作并返回。
通過NAPI框架進行C/C++與JS數據類型的轉換
- OpenHarmony NAPI將ECMAScript標準中定義的Boolean、Null、Undefined、Number、BigInt、String、Symbol和Object八種數據類型,以及函數對應的Function類型,統一封裝成napi_value類型,下文中表述為JS類型,用于接收ArkUI應用傳遞過來的數據及返回數據給ArkUI應用。
ECMAScript是一種由Ecma國際(通過ECMA-262標準化的腳本程序設計語言。這種語言在萬維網上應用廣泛,它往往被稱為JavaScript或JScript,所以它可以理解為是JavaScript的一個標準,但實際上后兩者是ECMA-262標準的實現和擴展。
- 下面通過擴展一個簡單的接口——Add(num1, num2)講述具體細節,接口使用同步方式實現,NAPI的同步方式調用的擴展API代碼處理流程如下圖。
.cpp源碼實現
- 在《??三方庫移植之NAPI開發[1]—Hello OpenHarmony NAPI ??》一文的基礎上修改hellonapi.cpp文件,其余文件不變。
- hellonapi.cpp內容如下:
.cpp源碼解析
注冊NAPI模塊、添加接口聲明
接口業務實現C/C++代碼
獲取參數
- NAPI定義API方法時的接收參數為(napi_env, napi_callback_info)
- 其中napi_callback_info為上下文的信息。
- NAPI提供了napi_get_cb_info()方法可從napi_callback_info中獲取參數列表、this及其他數據。
napi_get_cb_info函數在ohos3.2beta3源碼foundation/arkui/napi/native_engine/native_api.cpp中。
napi_get_cb_info函數說明如下:
- 參數說明:
- [in] env: 傳入接口調用者的環境,包含js引擎等,由框架提供,默認情況下直接傳入即可。
- [in] cbinfo: napi_callback_info對象,上下文的信息。
- [in-out] argc: argv數組的長度。若napi_callback_info中實際包含的參數的個數大于請求的數量argc,將只復制argc的值所指定數量的參數只argv中。若實際的參數個數小于請求的數量,將復制全部的參數,數組多余的空間用空值填充,并將參數實際長度寫入argc。
- [out] argv: 用于接收參數列表。
- [out] this_arg: 用于接收this對象。
- [out] data: NAPI的上下文數據 返回值:返回napi_ok表示轉換成功,其他值失敗。下面的返回napi_status方法一樣。
- 在Add方法中,調用napi_get_cb_info函數:
JS類型值轉換為C/C++類型的值
- 此示例中傳入的參數是Javascript值類型,被NAPI框架封裝成統一的唯一類型——napi_value類型,為了能夠進行計算,我們需要獲取其對應在C/C++中的類型的值。
- NAPI提供了包括以下方法以便獲取不同類型的值(ohos3.2beta3源碼foundation/arkui/napi/native_engine/native_api.cpp中)
- napi_get_value_double
- napi_get_value_int32
- napi_get_value_uint32
- napi_get_value_int64
- napi_get_value_bool
- napi_get_value_string_latin1(Copies LATIN-1 encoded bytes from a string into a buffer)
- napi_get_value_string_utf8(Copies UTF-8 encoded bytes from a string into a buffer)
- napi_get_value_string_utf16
- napi_get_value_external
- napi_get_value_bigint_int64
- napi_get_value_bigint_uint64
- napi_get_value_bigint_words
- 此示例hellonapi.cpp中使用到了napi_get_value_double方法,函數定義如下:
參數說明:
- [in] env: 傳入接口調用者的環境,包含js引擎等,由框架提供,默認情況下直接傳入即可。
- [in] value: 傳入要轉換的napi_value類型數據對象(可視為一個JS對象)。
- [out] result: 轉換出對應類型(double)結果。 返回值:返回napi_ok表示轉換成功,其他值失敗。
獲取參數的C/C++類型的值前,需要先判斷值的類型,本示例需要判斷傳入參數的JS值必須為number類型
- NAPI框架提供了napi_typeof方法用于獲取指定對象的類型,其函數定義如下:
參數說明:
- [in] env: 傳入接口調用者的環境,包含js引擎等,由框架提供,默認情況下直接傳入即可。
- [in] value: 傳入要轉換的napi_value類型數據對象(可視為一個JS對象)。
- [out] result: 返回value參數對應的JS類型。
- napi_valuetype對應了ECMAScript標準中定義的Boolean、Null、Undefined、Number、BigInt、String、Symbol和Object八種數據類型,以及函數對應的Function類型。
- 另外,napi_valuetype還包括了一個napi_external類型,其表示沒有任何屬性也沒有任何原型的對象。
綜上所述參數類型判斷及值轉換,示例代碼如下:
計算結果轉換為JS類型并返回
- 計算的結果是C/C++類型,需要轉換成NAPI node_value類型返回給JS。
- NAPI提供了一些方法以便將C/C++不同類型的值轉為node_value類型,返回給JS代碼。例如:
- napi_create_double
- napi_create_int32
- napi_create_uint32
- napi_create_int64
- napi_create_string_latin1
- napi_create_string_utf8
- napi_create_string_utf16
- 以napi_create_double方法為例,函數定義如下:
參數說明:
[in] env: 傳入接口調用者的環境,包含js引擎等,由框架提供,默認情況下直接傳入即可。
[in] value: 傳入要轉換的double類型數據值。
[out] result: 轉換出結果。
ArkUI應用實現代碼
ArkUI應用實現目錄結構。
index.ets內容如下:
index.ets
效果圖如下:
index.ets解析
- 參數說明
字段 | 類型 | 說明 |
tittle | string | 標題 |
message | string | 說明 |
tipsNum1 | number | 提示輸入第一個參數 |
tipsNum2 | number | 提示輸入第二個參數 |
tipsResult | string | 提示結果 |
buttonSubmit | string | 計算按鈕名稱 |
result | string | 結果 |
num1 | number | 輸入的第一個數 |
num2 | number | 輸入的第二個數 |
- 設置參數
- 界面實現
- 綁定事件、關聯參數
兩個TextInput組件分別綁定onChange事件,并分別關聯num1,num2來記錄輸入的參數。
- Button組件添加點擊事件,調用hellonapiu.cpp中的Add方法(調用js中的add,add和Add已經在napi.cpp中綁定)。
- 通過NAPI框架輸入到C的Add函數的JS參數是num1和num2,輸出的JS參數是result。
@ohos.hellonapi.d.ts接口文檔
總結
hellonapi.cpp:
index.ets: