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