天天看點

#打卡不停更#三方庫移植之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内容如下:
#include <string.h>
#include "napi/native_node_api.h"
#include "napi/native_api.h"

//NAPI定義API方法(接口業務實作)時的接收參數為(napi_env, napi_callback_info),
static napi_value Add(napi_env env, napi_callback_info info) {

    //擷取2個參數,值的類型是js類型(napi_value)
    size_t requireArgc = 2;
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    //NAPI提供了napi_get_cb_info()方法可從napi_callback_info中擷取參數清單、this及其他資料
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    
    //擷取并判斷js參數類型
    napi_valuetype valuetype0;
    NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));

    napi_valuetype valuetype1;
    NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));

    if (valuetype0 != napi_number || valuetype1 != napi_number) {
    napi_throw_type_error(env, NULL, "Wrong arguments. 2 numbers are expected.");
    return NULL;
  }
    
    //将js類型(napi_value)的參數值轉換成C++類型double
    double value0;
    NAPI_CALL(env, napi_get_value_double(env, args[0], &value0));

    double value1;
    NAPI_CALL(env, napi_get_value_double(env, args[1], &value1));

    //将結果由C++類型(double)轉換成js類型(napi_value)
    //NAPI提供了一些方法以便将C/C++不同類型的值轉為node_value類型,傳回給JS代碼。
    napi_value sum;
    NAPI_CALL(env, napi_create_double(env, value0 + value1, &sum));
    
   //傳回napi_value類型結果
    return sum;
}

// napi_addon_register_func
//2.指定子產品注冊對外接口的處理函數,具體擴充的接口在該函數中聲明
static napi_value registerFunc(napi_env env, napi_value exports)
{

    // 在napi_property_descriptor desc[]中将編寫C的“Add方法與對外暴露Js的接口“add”方法進行關聯
    static napi_property_descriptor desc[] = {
        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;   
}

// 1.先定義napi_module,指定目前NAPI子產品對應的子產品名
//以及子產品注冊對外接口的處理函數,具體擴充的接口在該函數中聲明
// nm_modname: 子產品名稱,對應eTS代碼為import nm_modname from '@ohos.ohos_shared_library_name'
//示例對應eTS代碼為:import hellonapi from '@ohos.hellonapi'
static napi_module hellonapiModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = registerFunc, // 子產品對外接口注冊函數
    .nm_modname = "hellonapi",  // 自定義子產品名
    .nm_priv = ((void*)0),
    .reserved = { 0 },
};

//3.子產品定義好後,調用NAPI提供的子產品注冊函數napi_module_register(napi_module* mod)函數注冊到系統中。
// register module,裝置啟動時自動調用此constructor函數,把子產品定義的子產品注冊到系統中
extern "C" __attribute__((constructor)) void hellonapiModuleRegister()
{
    napi_module_register(&hellonapiModule);
}
           

.cpp源碼解析

注冊NAPI子產品、添加接口聲明

// napi_addon_register_func
//2.指定子產品注冊對外接口的處理函數,具體擴充的接口在該函數中聲明
static napi_value registerFunc(napi_env env, napi_value exports)
{
    static napi_property_descriptor desc[] = {
        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;   
}

// 1.先定義napi_module,指定目前NAPI子產品對應的子產品名
//以及子產品注冊對外接口的處理函數,具體擴充的接口在該函數中聲明
// nm_modname: 子產品名稱,對應eTS代碼為import nm_modname from '@ohos.ohos_shared_library_name'
//示例對應eTS代碼為:import hellonapi from '@ohos.hellonapi'
static napi_module hellonapiModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = registerFunc, // 子產品對外接口注冊函數
    .nm_modname = "hellonapi",  // 自定義子產品名
    .nm_priv = ((void*)0),
    .reserved = { 0 },
};

//3.子產品定義好後,調用NAPI提供的子產品注冊函數napi_module_register(napi_module* mod)函數注冊到系統中。
// register module,裝置啟動時自動調用此constructor函數,把子產品定義的子產品注冊到系統中
extern "C" __attribute__((constructor)) void hellonapiModuleRegister()
{
    napi_module_register(&hellonapiModule);
}
           

接口業務實作C/C++代碼

//NAPI定義API方法(接口業務實作)時的接收參數為(napi_env, napi_callback_info),
//其中napi_callback_info為上下文的資訊
static napi_value Add(napi_env env, napi_callback_info info) {

    //擷取2個參數,值的類型是js類型(napi_value)
    size_t requireArgc = 2;
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    
    //NAPI架構提供了napi_typeof方法用于擷取指定js參數類型
    napi_valuetype valuetype0;
    NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));

    napi_valuetype valuetype1;
    NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));

    if (valuetype0 != napi_number || valuetype1 != napi_number) {
    napi_throw_type_error(env, NULL, "Wrong arguments. 2 numbers are expected.");
    return NULL;
  }
    
    //将js類型(napi_value)的參數值轉換成C++類型double
    double value0;
    NAPI_CALL(env, napi_get_value_double(env, args[0], &value0));

    double value1;
    NAPI_CALL(env, napi_get_value_double(env, args[1], &value1));

    //将結果由C++類型(double)轉換成js類型(napi_value)
    napi_value sum;
    NAPI_CALL(env, napi_create_double(env, value0 + value1, &sum));
    
   //傳回napi_value類型結果
    return sum;
}
           

擷取參數

static napi_value Add(napi_env env, napi_callback_info info) {
......
}
           
  • NAPI定義API方法時的接收參數為(napi_env, napi_callback_info)
    • 其中napi_callback_info為上下文的資訊。
  • NAPI提供了napi_get_cb_info()方法可從napi_callback_info中擷取參數清單、this及其他資料。
    #打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換

napi_get_cb_info函數在ohos3.2beta3源碼foundation/arkui/napi/native_engine/native_api.cpp中

// Methods to work with napi_callbacks
// Gets all callback info in a single call. (Ugly, but faster.)
NAPI_EXTERN napi_status napi_get_cb_info(napi_env env,              // [in] NAPI environment handle
                                         napi_callback_info cbinfo, // [in] Opaque callback-info handle
                                         size_t* argc,         // [in-out] Specifies the size of the provided argv array
                                                               // and receives the actual count of args.
                                         napi_value* argv,     // [out] Array of values
                                         napi_value* this_arg, // [out] Receives the JS 'this' arg for the call
                                         void** data)          // [out] Receives the data pointer for the callback.
{
    CHECK_ENV(env);
    CHECK_ARG(env, cbinfo);

    auto info = reinterpret_cast<NativeCallbackInfo*>(cbinfo);

    if ((argc != nullptr) && (argv != nullptr)) {
        size_t i = 0;
        for (i = 0; (i < *argc) && (i < info->argc); i++) {
            argv[i] = reinterpret_cast<napi_value>(info->argv[i]);
        }
        *argc = i;
    }

    if (argc != nullptr) {
        *argc = info->argc;
    }

    if (this_arg != nullptr) {
        *this_arg = reinterpret_cast<napi_value>(info->thisVar);
    }

    if (data != nullptr && info->functionInfo != nullptr) {
        *data = info->functionInfo->data;
    }

    return napi_clear_last_error(env);
}
           

napi_get_cb_info

函數說明如下:

napi_status napi_get_cb_info(napi_env env,              
                             napi_callback_info cbinfo, 
                             size_t* argc,                          
                             napi_value* argv,     
                             napi_value* this_arg, 
                             void** data)         
           
  • 參數說明:
    • [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函數:
// env、info 參數由NAPI架構傳入
static napi_value Add(napi_env env, napi_callback_info info) {
size_t requireArgc = 2;
  size_t argc = 2;
  napi_value args[2] = {nullptr};
  NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
  napi_value sum;
  return sum;
}
           

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方法,函數定義如下:
      #打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換
NAPI_EXTERN napi_status napi_get_value_double(napi_env env, napi_value value, double* result)
{
    CHECK_ENV(env);
    CHECK_ARG(env, value);
    CHECK_ARG(env, result);

    auto nativeValue = reinterpret_cast<NativeValue*>(value);

    RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_NUMBER, napi_number_expected);

    *result = *reinterpret_cast<NativeNumber*>(nativeValue->GetInterface(NativeNumber::INTERFACE_ID));
    return napi_clear_last_error(env);
}
           

參數說明:

  • [in] env: 傳入接口調用者的環境,包含js引擎等,由架構提供,預設情況下直接傳入即可。
  • [in] value: 傳入要轉換的napi_value類型資料對象(可視為一個JS對象)。
  • [out] result: 轉換出對應類型(double)結果。 傳回值:傳回napi_ok表示轉換成功,其他值失敗。

擷取參數的C/C++類型的值前,需要先判斷值的類型,本示例需要判斷傳入參數的JS值必須為number類型

  • NAPI架構提供了napi_typeof方法用于擷取指定對象的類型,其函數定義如下:
// Methods to get the native napi_value from Primitive type
NAPI_EXTERN napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
{
    CHECK_ENV(env);
    CHECK_ARG(env, value);
    CHECK_ARG(env, result);

    auto nativeValue = reinterpret_cast<NativeValue*>(value);

    *result = (napi_valuetype)nativeValue->TypeOf();
    return napi_clear_last_error(env);
}
           
#打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換

參數說明:

  • [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類型,其表示沒有任何屬性也沒有任何原型的對象。

綜上所述參數類型判斷及值轉換,示例代碼如下:

static napi_value Add(napi_env env, napi_callback_info info) {
    // 1. 擷取2個參數,值的類型是js類型(napi_value)
    size_t requireArgc = 2;
    size_t argc = 2;
    napi_value args[2] = {nullptr};

    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));

    // 2. 擷取并判斷js參數類型
    napi_valuetype valuetype0;
    NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));

    napi_valuetype valuetype1;
    NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));

    //輸入的資料類型異常處理
    if (valuetype0 != napi_number || valuetype1 != napi_number) {
    napi_throw_type_error(env, NULL, "Wrong arguments. 2 numbers are expected.");
    return NULL;
  }

    // 3. 将js類型(napi_value)的參數值轉換成C++類型double
    double value0;
    NAPI_CALL(env, napi_get_value_double(env, args[0], &value0));

    double value1;
    NAPI_CALL(env, napi_get_value_double(env, args[1], &value1));

    napi_value sum;
    return sum;
           

計算結果轉換為JS類型并傳回

static napi_value Add(napi_env env, napi_callback_info info) {
···
  // 4. 将結果由C++類型(double)轉換成js類型(napi_value)
  napi_value sum;
  NAPI_CALL(env, napi_create_double(env, value0 + value1, &sum));
··· 
}
           
  • 計算的結果是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方法為例,函數定義如下:
#打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換
NAPI_EXTERN napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
{
    CHECK_ENV(env);
    CHECK_ARG(env, result);

    auto engine = reinterpret_cast<NativeEngine*>(env);
    auto resultValue = engine->CreateNumber(value);

    *result = reinterpret_cast<napi_value>(resultValue);
    return napi_clear_last_error(env);
}
           

參數說明:

[in] env: 傳入接口調用者的環境,包含js引擎等,由架構提供,預設情況下直接傳入即可.

[in] value: 傳入要轉換的double類型資料值.

[out] result: 轉換出結果

ArkUI應用實作代碼

ArkUI應用實作目錄結構

#打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換

index.ets内容如下:

index.ets

import hellonapi from '@ohos.hellonapi'

@Entry
@Component
export struct HelloNAPI {
  private textInputController1: TextInputController = new TextInputController()
  private textInputController2: TextInputController = new TextInputController()
  private tittle: string = 'C/C++與JS的資料類型轉換'
  private message: string = '計算x+y'
  private tipsNum1: string = '請輸入X:'
  private tipsNum2: string = '請輸入Y:'
  private tipsResult: string = '結果:'
  private buttonSubmit: string = '計算'
  @State result: number = 0.0
  @State num1: number = 0.0
  @State num2: number = 0.0

  build() {
    Row() {
      Column() {
        Row(){
          Text(this.tittle).height('100%').align(Alignment.Center).fontSize(50).fontWeight(800)
        }.height('30%').width('100%').justifyContent(FlexAlign.Center)

        Row(){
          Text(this.message).height('100%').align(Alignment.Center).fontSize(35).fontWeight(500)
        }.height('15%').width('100%').justifyContent(FlexAlign.Center)

        Row(){
          Text(this.tipsNum1).fontColor(Color.Black).fontSize('65px').width('30%').height('100%').margin({left:30})
          TextInput({ placeholder: 'X', controller:this.textInputController1}).type(InputType.Number)
            .height('100%').width('60%').margin({left:10,right:30}).fontSize('25px')
            .onChange(value =>{this.num1 = parseFloat(value)})
        }.height('6%').width('100%').justifyContent(FlexAlign.Start)

        Row(){
          Text(this.tipsNum2).fontColor(Color.Black).fontSize('65px').width('30%').height('100%').margin({left:30})
          TextInput({ placeholder: 'Y', controller:this.textInputController2}).type(InputType.Number)
            .height('100%').width('60%').margin({left:10,right:30}).fontSize('25px')
            .onChange(value =>{this.num2 = parseFloat(value)})
        }.height('6%').width('100%').margin({top:20})

        Row(){
          Text(this.tipsResult).fontColor(Color.Black).fontSize(35).width('40%').height('100%').margin({left:30})
          Text(''+this.result).fontColor(Color.Black).fontSize(35).width('60%').height('100%')
        }.height('10%').width('100%').touchable(false)

        Row(){
          Button(this.buttonSubmit)
            .fontSize(37)
            .fontWeight(FontWeight.Bold)
            .margin({top:5})
            .height(80)
            .width(200)
            .onClick(() => {

              //hellonapi為BUILD.gn檔案中定義的ohos_shared_library結構體名稱
              this.result = hellonapi.add(this.num1,this.num2)
            })
        }.height('30%').width('100%').justifyContent(FlexAlign.Center)
      }
      .width('100%')
    }
    .height('100%')
  }
}
           

效果圖如下:

#打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換

index.ets解析

  • 參數說明
字段 類型 說明
tittle string 标題
message string 說明
tipsNum1 number 提示輸入第一個參數
tipsNum2 number 提示輸入第二個參數
tipsResult string 提示結果
buttonSubmit string 計算按鈕名稱
result string 結果
num1 number 輸入的第一個數
num2 number 輸入的第二個數
  • 設定參數
import hellonapi from '@ohos.hellonapi'

@Entry
@Component
export struct HelloNAPI {
  private textInputController1: TextInputController = new TextInputController()
  private textInputController2: TextInputController = new TextInputController()
  private tittle: string = 'C/C++與JS的資料類型轉換'
  private message: string = '計算x+y'
  private tipsNum1: string = '請輸入X:'
  private tipsNum2: string = '請輸入Y:'
  private tipsResult: string = '結果:'
  private buttonSubmit: string = '計算'
  @State result: number = 0.0
  @State num1: number = 0.0
  @State num2: number = 0.0
  ...
  build() {
   ...
  }
}
           
  • 界面實作
import hellonapi from '@ohos.hellonapi'

@Entry
@Component
export struct HelloNAPI {
  ...
 build() {
    Row() {
      Column() {
        Row(){
          Text(this.tittle).height('100%').align(Alignment.Center).fontSize(50).fontWeight(800)
        }.height('30%').width('100%').justifyContent(FlexAlign.Center)

        Row(){
          Text(this.message).height('100%').align(Alignment.Center).fontSize(35).fontWeight(500)
        }.height('15%').width('100%').justifyContent(FlexAlign.Center)

        Row(){
          Text(this.tipsNum1).fontColor(Color.Black).fontSize('65px').width('30%').height('100%').margin({left:30})
          TextInput({ placeholder: 'X', controller:this.textInputController1}).type(InputType.Number)
            .height('100%').width('60%').margin({left:10,right:30}).fontSize('25px')
            .onChange(value =>{this.num1 = parseFloat(value)})
        }.height('6%').width('100%').justifyContent(FlexAlign.Start)

        Row(){
          Text(this.tipsNum2).fontColor(Color.Black).fontSize('65px').width('30%').height('100%').margin({left:30})
          TextInput({ placeholder: 'Y', controller:this.textInputController2}).type(InputType.Number)
            .height('100%').width('60%').margin({left:10,right:30}).fontSize('25px')
            .onChange(value =>{this.num2 = parseFloat(value)})
        }.height('6%').width('100%').margin({top:20})

        Row(){
          Text(this.tipsResult).fontColor(Color.Black).fontSize(35).width('40%').height('100%').margin({left:30})
          Text(''+this.result).fontColor(Color.Black).fontSize(35).width('60%').height('100%')
        }.height('10%').width('100%').touchable(false)

        Row(){
          Button(this.buttonSubmit)
            .fontSize(37)
            .fontWeight(FontWeight.Bold)
            .margin({top:5})
            .height(80)
            .width(200)
            .onClick(() => {

              //hellonapi為BUILD.gn檔案中定義的ohos_shared_library結構體名稱
              this.result = hellonapi.add(this.num1,this.num2)
            })
        }.height('30%').width('100%').justifyContent(FlexAlign.Center)
      }
      .width('100%')
    }
    .height('100%')
  }
}
           
  • 綁定事件、關聯參數

    兩個TextInput元件分别綁定onChange事件,并分别關聯num1,num2來記錄輸入的參數

Row(){
          Text(this.tipsNum1).fontColor(Color.Black).fontSize('65px').width('30%').height('100%').margin({left:30})
          TextInput({ placeholder: 'X', controller:this.textInputController1}).type(InputType.Number)
            .height('100%').width('60%').margin({left:10,right:30}).fontSize('25px')
            .onChange(value =>{this.num1 = parseFloat(value)})
        }.height('6%').width('100%').justifyContent(FlexAlign.Start)

        Row(){
          Text(this.tipsNum2).fontColor(Color.Black).fontSize('65px').width('30%').height('100%').margin({left:30})
          TextInput({ placeholder: 'Y', controller:this.textInputController2}).type(InputType.Number)
            .height('100%').width('60%').margin({left:10,right:30}).fontSize('25px')
            .onChange(value =>{this.num2 = parseFloat(value)})
        }.height('6%').width('100%').margin({top:20})
           
  • Button元件添加點選事件,調用hellonapiu.cpp中的Add方法(調用js中的add,add和Add已經在napi.cpp中綁定)
Row(){
          Button(this.buttonSubmit)
            .fontSize(37)
            .fontWeight(FontWeight.Bold)
            .margin({top:5})
            .height(80)
            .width(200)
            .onClick(() => {

              //hellonapi為BUILD.gn檔案中定義的ohos_shared_library結構體名稱
            this.result = hellonapi.add(this.num1,this.num2)
            })
           
  • 通過NAPI架構輸入到C的Add函數的JS參數是num1和num2,輸出的JS參數是result

@ohos.hellonapi.d.ts接口文檔

declare namespace hellonapi {
	export const add: (a: number, b: number) => number;
    /**
     * 
     *
     * @since 9
     * @syscap SystemCapability.Ability.AbilityRuntime.AbilityCore
     */

}
export default hellonapi;
           

總結

hellonapi.cpp

#打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換

index.ets

#打卡不停更#三方庫移植之NAPI開發[2]C/C++與JS的資料類型轉換

附件連結:mysubsys子系統、arkui應用和接口檔案.zip