鸿蒙-ArkTS和Native之间的交互使用2如何调用Napi

仿佛云烟
发布于 2025-6-28 16:45
浏览
0收藏
引言:

鸿蒙-ArkTS和Native之间的交互使用2如何调用Napi-鸿蒙开发者社区


HarmonyOS NDK提供多个开放能力库,如图形图像、内存管理、设备管理等,供开发者实现代码逻辑;同时提供业界标准库,如​​libc标准库​​​、​​标准C++库​​​、​​Node-API​​等。


首先:Native侧方法的实现


1.实现ArkTS接口与C++接口的绑定和映射。


// entry/src/main/cpp/napi_init.cpp
EXTERN_C_START
// 模块初始化
static napi_value Init(napi_env env, napi_value exports) {
    // ArkTS接口与C++接口的绑定和映射
    napi_property_descriptor desc[] = {
        // 注:仅需复制以下两行代码,Init在完成创建Native C++工程以后在napi_init.cpp中已配置好。
        {"callNative", nullptr, CallNative, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeCallArkTS", nullptr, NativeCallArkTS, nullptr, nullptr, nullptr, napi_default, nullptr}
    };
    // 在exports对象上挂载CallNative/NativeCallArkTS两个Native方法
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END


2.在index.d.ts文件中,提供JS侧的接口方法。


// entry/src/main/cpp/types/libentry/index.d.ts
export const callNative: (a: number, b: number) => number;
export const nativeCallArkTS: (cb: (a: number) => number) => number;


3.在oh-package.json5文件中将index.d.ts与cpp文件关联起来。


// entry/src/main/cpp/types/libentry/oh-package.json5
{
  "name": "libentry.so",
  "types": "./index.d.ts",
  "version": "",
  "description": "Please describe the basic information."
}


4.在CMakeLists.txt文件中配置CMake打包参数。


# entry/src/main/cpp/CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
project(MyApplication2)


set(NATIVERENDER_ROOT_PATH {NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include)


# 添加名为entry的库
add_library(entry SHARED napi_init.cpp)
# 构建此可执行文件需要链接的库
target_link_libraries(entry PUBLIC libace_napi.z.so)


5.实现Native侧的CallNative以及NativeCallArkTS接口。具体代码如下:


// entry/src/main/cpp/napi_init.cpp
static napi_value CallNative(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    // 声明参数数组
    napi_value args[2] = {nullptr};


    // 获取传入的参数并依次放入参数数组中
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);


    // 依次获取参数
    double value0;
    napi_get_value_double(env, args[0], &value0);
    double value1;
    napi_get_value_double(env, args[1], &value1);


    // 返回两数相加的结果
    napi_value sum;
    napi_create_double(env, value0 + value1, &sum);
    return sum;
}


static napi_value NativeCallArkTS(napi_env env, napi_callback_info info)
{    
    size_t argc = 1;
    // 声明参数数组
    napi_value args[1] = {nullptr};


    // 获取传入的参数并依次放入参数数组中
    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);


    // 创建一个int,作为ArkTS的入参
    napi_value argv = nullptr;    
    napi_create_int32(env, 2, &argv );


    // 调用传入的callback,并将其结果返回
    napi_value result = nullptr;
    napi_call_function(env, nullptr, args[0], 1, &argv, &result);
    return result;
}


ArkTS侧调用C/C++方法实现


ArkTS侧通过import引入Native侧包含处理逻辑的so来使用C/C++的方法。


// entry/src/main/ets/pages/Index.ets
// 通过import的方式,引入Native能力。
import nativeModule from 'libentry.so'


@Entry
@Component
struct Index {
  @State message: string = 'Test Node-API callNative result: ';
  @State message2: string = 'Test Node-API nativeCallArkTS result: ';
  build() {
    Row() {
      Column() {
        // 第一个按钮,调用add方法,对应到Native侧的CallNative方法,进行两数相加。
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.message += nativeModule.callNative(2, 3);
            })
        // 第二个按钮,调用nativeCallArkTS方法,对应到Native的NativeCallArkTS,在Native调用ArkTS function。
        Text(this.message2)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.message2 += nativeModule.nativeCallArkTS((a: number)=> {
                return a * 2;
            });
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}


以上就是使用Node-API实现跨语言交互:


  • ArkTS侧:实现C++方法的调用。代码比较简单,import一个对应的so库后,即可调用C++方法。
  • Native侧:.cpp文件,实现模块的注册。需要提供注册lib库的名称,并在注册回调方法中定义接口的映射关系,即Native方法及对应的JS/ArkTS接口名称等。



分类
收藏
回复
举报
回复
    相关推荐