文档管理中心
我的
您当前浏览的HarmonyOS 5.0.1(API 13)文档归档不再维护,推荐您使用最新版本。详细请参考文档维护策略变更。
指南NDK开发代码开发使用Node-API实现跨语言交互Node-API使用指导使用Node-API接口进行函数创建和调用

使用Node-API接口进行函数创建和调用

简介

函数调用允许开发者从Node-API模块中调用ArkTS函数,并传递参数进行调用,或者直接在Node-API模块中创建一个ArkTS方法。

基本概念

函数是一种非常重要的编程概念,可以执行特定的任务或操作、提高代码的可读性、把复杂任务简化、提高代码复用性以及支持代码的组织与管理。每个函数可以负责不同的功能,提供一种将代码模块化和组织结构化的方式,使其更易于理解、维护和重用。

场景和功能介绍

展开
接口 描述
napi_get_cb_info 当需要从给定的callback info中获取有关调用的参数信息和this指针时,可使用此接口。
napi_call_function 当需要在Node-API模块中对ArkTS侧函数进行调用时,可使用此接口。
napi_create_function 当需要将C/C++函数创建一个ArkTS函数时,可以使用此接口。

使用示例

Node-API接口开发流程参考使用Node-API实现跨语言交互开发流程,本文仅对接口对应C++及ArkTS相关代码进行展示。napi_create_function方法除外,具体使用见示例。

napi_get_cb_info

获取有关函数调用的详细信息。

cpp部分代码

收起
自动换行
深色代码主题
复制
  1. #include "napi/native_api.h"
  2. // 获取ArkTS侧入参的的参数信息
  3. static napi_value GetCbArgs(napi_env env, napi_callback_info info)
  4. {
  5. size_t argc = 1;
  6. napi_value args[1] = {nullptr};
  7. napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
  8. return args[0];
  9. }
  10. // 获取ArkTS侧入参的参数个数
  11. static napi_value GetCbArgQuantity(napi_env env, napi_callback_info info)
  12. {
  13. size_t argc = 0;
  14. napi_value result = nullptr;
  15. napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
  16. napi_create_int32(env, argc, &result);
  17. return result;
  18. }
  19. // 获取ArkTS侧this参数
  20. static napi_value GetCbContext(napi_env env, napi_callback_info info)
  21. {
  22. napi_value thisArg = nullptr;
  23. napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr);
  24. return thisArg;
  25. }

接口声明

收起
自动换行
深色代码主题
复制
  1. // index.d.ts
  2. export const getCbArgs: <T>(arg: T) => T;
  3. // getCbArgQuantity的入参由用户自定义,在此用例中,我们用两个入参,一个是string,一个是number
  4. export const getCbArgQuantity: (str: string, num: number) => number;
  5. export const getCbContext: () => Object;

ArkTS 侧示例代码

收起
自动换行
深色代码主题
复制
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. function summation(arr: Array<number>) {
  4. let sum: number = 0;
  5. for (let i = 0; i < arr.length; i++) {
  6. sum += arr[i];
  7. }
  8. return sum;
  9. }
  10. const str = 'message';
  11. const arr = [0, 1, 2, 3, 4, 5];
  12. const num = 526;
  13. class Student {
  14. name: string;
  15. age: number;
  16. score: number;
  17. constructor(name: string, age: number, score: number) {
  18. this.name = name;
  19. this.age = age;
  20. this.score = score;
  21. }
  22. }
  23. let student = new Student('Alice', 18, 100);
  24. // 获取参数
  25. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get string arg:%{public}s', testNapi.getCbArgs(str));
  26. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get array arg:%{public}s ', testNapi.getCbArgs(arr).toString());
  27. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get num arg:%{public}d ', testNapi.getCbArgs(num));
  28. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get undefined arg:%{public}s ', testNapi.getCbArgs(undefined));
  29. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get object arg:%{public}s ', JSON.stringify(testNapi.getCbArgs(student)));
  30. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get function arg:%{public}d ', testNapi.getCbArgs(summation(arr)));
  31. // 获取参数个数
  32. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get arg quantity:%{public}d ', testNapi.getCbArgQuantity(str, num));
  33. // 获取上下文
  34. hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get thisArg:%{public}s ', testNapi.getCbContext().toString());

napi_call_function

在C/C++侧对ArkTS函数进行调用。

注意事项:napi_call_function传入的argv的长度必须大于等于argc声明的数量,且被初始化成nullptr。

cpp部分代码

收起
自动换行
深色代码主题
复制
  1. #include "napi/native_api.h"
  2. static napi_value CallFunction(napi_env env, napi_callback_info info)
  3. {
  4. size_t argc = 1;
  5. napi_value argv[1] = {nullptr};
  6. // 获取ArkTS侧入参
  7. napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
  8. // 获取全局对象,这里用global是因为napi_call_function的第二个参数是JS函数的this入参。
  9. napi_value global = nullptr;
  10. napi_get_global(env, &global);
  11. // 调用ArkTS方法
  12. napi_value result = nullptr;
  13. // 调用napi_call_function时传入的argv的长度必须大于等于argc声明的数量,且被初始化成nullptr
  14. napi_call_function(env, global, argv[0], argc, argv, &result);
  15. return result;
  16. }
  17. static napi_value ObjCallFunction(napi_env env, napi_callback_info info)
  18. {
  19. // 获取ArkTS侧传递的两个参数
  20. size_t argc = 2;
  21. napi_value argv[2] = {nullptr};
  22. // 获取ArkTS侧入参
  23. napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
  24. // 调用ArkTS方法
  25. napi_value result = nullptr;
  26. // 调用napi_call_function时传入的argv的长度必须大于等于argc声明的数量,且被初始化成nullptr
  27. napi_call_function(env, argv[0], argv[1], argc, argv, &result);
  28. return result;
  29. }

接口声明

收起
自动换行
深色代码主题
复制
  1. // index.d.ts
  2. export const callFunction: (func: Function) => number;
  3. export const objCallFunction: (obj: Object, func: Function) => number;

ArkTS 侧示例代码

收起
自动换行
深色代码主题
复制
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. function returnNumber() {
  4. return 10;
  5. }
  6. class Person {
  7. age(): number {
  8. return 11;
  9. }
  10. }
  11. const person = new Person();
  12. hilog.info(0x0000, 'testTag', 'Test Node-API call_function:%{public}d', testNapi.callFunction(returnNumber));
  13. hilog.info(0x0000, 'testTag', 'Test Node-API call_function:%{public}d', testNapi.objCallFunction(person,person.age));

napi_create_function

将一个C/C++函数包装为可在ArkTS中调用的函数,并返回一个表示该函数的napi_value。

cpp部分代码

收起
自动换行
深色代码主题
复制
  1. #include "napi/native_api.h"
  2. static napi_value CalculateArea(napi_env env, napi_callback_info info)
  3. {
  4. // 获取ArkTS侧传递的两个参数
  5. size_t argc = 2;
  6. napi_value args[2] = {nullptr};
  7. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  8. double width = 0;
  9. napi_get_value_double(env, args[0], &width);
  10. double height = 0;
  11. napi_get_value_double(env, args[1], &height);
  12. napi_value area = nullptr;
  13. napi_create_double(env, width * height, &area);
  14. return area;
  15. }
  16. EXTERN_C_START
  17. static napi_value Init(napi_env env, napi_value exports) {
  18. napi_value fn = nullptr;
  19. napi_create_function(env, nullptr, 0, CalculateArea, nullptr, &fn);
  20. napi_set_named_property(env, exports, "calculateArea", fn);
  21. return exports;
  22. }
  23. EXTERN_C_END

接口声明

收起
自动换行
深色代码主题
复制
  1. // index.d.ts
  2. export const calculateArea: (width: number, height: number) => number;

ArkTS 侧示例代码

收起
自动换行
深色代码主题
复制
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. hilog.info(0x0000, 'testTag', 'Test Node-API create_function:%{public}d ', testNapi.calculateArea(1.2, 4));

以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):

收起
自动换行
深色代码主题
复制
  1. // CMakeLists.txt
  2. add_definitions( "-DLOG_DOMAIN=0xd0d0" )
  3. add_definitions( "-DLOG_TAG=\"testTag\"" )
  4. target_link_libraries(entry PUBLIC libhilog_ndk.z.so)