鸿蒙5.0&next开发【利用Node-API扩展能力接口】NDK开发 ...

打印 上一主题 下一主题

主题 1015|帖子 1015|积分 3045

利用Node-API扩展能力接口

简介

[扩展能力]接口进一步扩展了Node-API的功能,提供了一些额外的接口,用于在Node-API模块中与ArkTS进行更灵活的交互和定制,这些接口可以用于创建自界说ArkTS对象等场景。
模块加载

接口描述

接口描述napi_load_module用于在Node-API模块中将abc文件作为模块加载,返回模块的命名空间,适用于需要在运行时动态加载模块或资源的应用程序,从而实现灵活的扩展和定制。napi_load_module_with_info用于在Node-API中进行模块的加载,当模块加载出来之后,可以利用函数napi_get_property获取模块导出的变量,也可以利用napi_get_named_property获取模块导出的函数,该函数可以在[新创建的ArkTs基础运行时情况]中利用。napi_module_register有些功能大概需要通过Node-API模块来实现以获得更好的性能,通过将这些功能实现为自界说模块并注册到ArkTS情况中,可以在肯定程度上提高团体的性能。 利用示例

napi_load_module

napi_load_module_with_info

napi_module_register

在ArkTS代码情况中利用Node-API模块编写的代码来实现特定的功能,可以将这部分功能封装成自界说模块,然后通过napi_module_register将其注册到ArkTS代码情况中,以实现功能的扩展和复用。
cpp部分代码
  1. #include "napi/native_api.h"
  2. // 此模块是一个Node-API的回调函数
  3. static napi_value Add(napi_env env, napi_callback_info info)
  4. {
  5.     // 接受传入两个参数
  6.     size_t requireArgc = 2;
  7.     size_t argc = 2;
  8.     napi_value args[2] = {nullptr};
  9.     napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
  10.     // 将传入的napi_value类型的参数转化为double类型
  11.     double valueLeft;
  12.     double valueRight;
  13.     napi_get_value_double(env, args[0], &valueLeft);
  14.     napi_get_value_double(env, args[1], &valueRight);
  15.     // 将转化后的double值相加并转成napi_value返回给ArkTS代码使用
  16.     napi_value sum;
  17.     napi_create_double(env, valueLeft + valueRight, &sum);
  18.     return sum;
  19. }
  20. // C++函数Init用于初始化插件,用于将ArkTS层的函数或属性与C++层的函数进行关联
  21. EXTERN_C_START
  22. static napi_value Init(napi_env env, napi_value exports)
  23. {
  24.     // 通过napi_property_descriptor结构体,可以定义需要导出的属性,并在Node-API模块中使用。napi_define_properties将属性与实际的C++函数进行关联,使其可以被ArkTS层访问和调用
  25.     napi_property_descriptor desc[] = {
  26.         { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
  27.     };
  28.     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  29.     return exports;
  30. }
  31. EXTERN_C_END
  32. // 插件的初始化被定义在一个名为demoModule的结构体中,其中包含了模块的基本信息,比如模块的版本号、注册函数等
  33. static napi_module demoModule = {
  34.     .nm_version =1,
  35.     .nm_flags = 0,
  36.     .nm_filename = nullptr,
  37.     .nm_register_func = Init,
  38.     .nm_modname = "entry",
  39.     .nm_priv = ((void*)0),
  40.     .reserved = { 0 },
  41. };
  42. // 在RegisterEntryModule函数中,使用napi_module_register函数注册并导出了这个插件
  43. extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
  44. {
  45.     napi_module_register(&demoModule);
  46. }
  47. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const add: (a: number, b: number) => number;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. hilog.info(0x0000, 'testTag', 'Test Node-API 2 + 3 = %{public}d', testNapi.add(2, 3));
  4. ts
复制代码
ArkTS Object相干

接口描述

接口描述napi_create_object_with_properties用于在Node-API模块中利用给定的napi_property_descriptor创建ArkTS Object。descriptor的键名必须为string,且不可转为number。napi_create_object_with_named_properties用于在Node-API模块中利用给定的napi_value和键名创建ArkTS Object。键名必须为string,且不可转为number。 利用示例

napi_create_object_with_properties

用给定的napi_property_descriptor作为属性去创建一个ArkTS对象,而且descriptor的键名必须为string,且不可转为number。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value CreateObjectWithProperties(napi_env env, napi_callback_info info)
  3. {
  4.     size_t argc = 1;
  5.     napi_value argv[1] = {nullptr};
  6.     // 获取解析传递的参数
  7.     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
  8.     // 声明了一个napi_property_descriptor数组desc,其中包含了一个名为"name"的属性,其值为传入的第一个参数argv[0]。
  9.     napi_property_descriptor desc[] = {
  10.         {"name", nullptr, nullptr, nullptr, nullptr, argv[0], napi_default_jsproperty, nullptr}};
  11.     napi_value object = nullptr;
  12.     // 调用napi_create_object_with_properties来创建一个新的ArkTS对象,并将属性值添加到该对象中。
  13.     napi_create_object_with_properties(env, &object, sizeof(desc) / sizeof(desc[0]), desc);
  14.     napi_valuetype valueType;
  15.     napi_typeof(env, object, &valueType);
  16.     if (valueType == napi_object) {
  17.         return object;
  18.     }
  19. }
  20. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const createObjectWithProperties: (data: string) => Object;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = testNapi.createObjectWithProperties('createObject');
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_create_object_with_properties:%{public}s', JSON.stringify(value));
  5. ts
复制代码
napi_create_object_with_named_properties

用于利用给定的napi_value和键名创建一个ArkTS对象,而且给定的键名必须为string,且不可转为number。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value CreateObjectWithNameProperties(napi_env env, napi_callback_info info)
  3. {
  4.     size_t argc = 1;
  5.     napi_value argv[1] = {nullptr};
  6.     // 获取解析传递的参数
  7.     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
  8.     napi_value obj = nullptr;
  9.     const char *key[] = {
  10.         "name",
  11.     };
  12.     const napi_value values[] = {
  13.         argv[0],
  14.     };
  15.     napi_property_descriptor desc[] = {{"name", nullptr, nullptr,
  16.                                         nullptr, nullptr, nullptr, napi_default, nullptr}};
  17.     napi_status status;
  18.     status = napi_create_object_with_named_properties(env, &obj, sizeof(desc) / sizeof(desc[0]), key, values);
  19.     if (status != napi_ok) {
  20.         return argv[0];
  21.     }
  22.     return obj;
  23. }
  24. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const createObjectWithNameProperties: (data: string) => string | { name: string };
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = testNapi.createObjectWithNameProperties('ls');
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_create_object_with_named_properties:%{public}s', JSON.stringify(value));
  5. ts
复制代码
运行指定abc文件

接口描述

接口描述napi_run_script_path用于在Node-API模块中运行指定abc文件。 利用示例

napi_run_script_path

在Node-API模块中运行abc文件。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value RunScriptPath(napi_env env, napi_callback_info info)
  3. {
  4.     napi_value value = nullptr;
  5.     // 注意:记得在应用rawfile目录下放置.abc文件
  6.     const char *scriptPath = "/entry/resources/rawfile/test.abc";
  7.     // 使用napi_run_script_path函数执行指定路径中的文件
  8.     napi_status status = napi_run_script_path(env, scriptPath, &value);
  9.     // 检查是否执行成功,如果失败,返回false
  10.     napi_value returnValue = nullptr;
  11.     if (value == nullptr || status != napi_ok) {
  12.         napi_get_boolean(env, false, &returnValue);
  13.     } else {
  14.         napi_get_boolean(env, true, &returnValue);
  15.     }
  16.     return returnValue;
  17. }
  18. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const runScriptPath: () => boolean;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. try {
  4.   // 在此处执行错误返回false,成功就返回true
  5.   hilog.info(0x0000, 'testTag', 'Test Node-API napi_run_script_path: %{public}s', testNapi.runScriptPath());
  6. } catch (error) {
  7.   hilog.error(0x0000, 'testTag', 'Test Node-API napi_run_script_path errorMessage: %{public}s', error.message);
  8. }
  9. ts
复制代码
test.js代码,将js代码编成.abc文件,步骤如下:

  • 在SDK的ets/build-tools/ets-loader/bin/ark/build-win/bin目次下放置test.js文件
  • 执行命令如es2abc.exe test.js --output test.abc后便可生成test.abc文件
放入指定路径中:/entry/resources/rawfile
  1. function add(a, b) {
  2.   return a+b;
  3. }
  4. add(1, 2);
  5. js
复制代码
异步工尴尬刁难象加入队列并指定优先级

接口描述

接口描述napi_queue_async_work_with_qos用于将异步工尴尬刁难象加入队列,让开发者可以大概根据QoS优先级来管理和调理异步工作的执行,从而更好地满意程序的性能和相应需求。 利用示例

napi_queue_async_work_with_qos

将异步工尴尬刁难象加到队列,由底层根据传入的qos优先级去调理执行。
给ArkTS对象绑定回调和回调所需的参数

接口描述

接口描述napi_coerce_to_native_binding_object用于给ArkTS对象绑定回调和回调所需的参数,其作用是为了给ArkTS对象携带Native信息。 利用示例

napi_coerce_to_native_binding_object

用于给ArkTS Object绑定回调和回调所需的参数,给ArkTS Object携带Native信息。
cpp部分代码
  1. #include <bits/alltypes.h>
  2. #include <hilog/log.h>
  3. #include <mutex>
  4. #include <unordered_set>
  5. #include <uv.h>
  6. #include "napi/native_api.h"
  7. class Object {
  8. public:
  9.     Object() = default;
  10.     ~Object() = default;
  11.     static Object* GetInstance()
  12.     {
  13.         Object* instance = new Object();
  14.         return instance;
  15.     }
  16.     static napi_value GetAddress(napi_env env, napi_callback_info info)
  17.     {
  18.         napi_value thisVar = nullptr;
  19.         napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
  20.         if (thisVar == nullptr) {
  21.             return nullptr;
  22.         }
  23.         void* object = nullptr;
  24.         napi_unwrap(env, thisVar, &object);
  25.         if (object == nullptr) {
  26.             return nullptr;
  27.         }
  28.         uint64_t addressVal = reinterpret_cast<uint64_t>(object);
  29.         napi_value address = nullptr;
  30.         napi_create_bigint_uint64(env, addressVal, &address);
  31.         return address;
  32.     }
  33.     // 获取数组大小
  34.     static napi_value GetSetSize(napi_env env, napi_callback_info info)
  35.     {
  36.         napi_value thisVar = nullptr;
  37.         napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
  38.         if (thisVar == nullptr) {
  39.             return nullptr;
  40.         }
  41.         void* object = nullptr;
  42.         napi_unwrap(env, thisVar, &object);
  43.         if (object == nullptr) {
  44.             return nullptr;
  45.         }
  46.         std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
  47.         uint32_t setSize = reinterpret_cast<Object*>(object)->numberSet_.size();
  48.         napi_value napiSize = nullptr;
  49.         napi_create_uint32(env, setSize, &napiSize);
  50.         return napiSize;
  51.     }
  52.     // 往数组里插入元素
  53.     static napi_value Store(napi_env env, napi_callback_info info)
  54.     {
  55.         size_t argc = 1;
  56.         napi_value args[1] = {nullptr};
  57.         napi_value thisVar = nullptr;
  58.         napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
  59.         if (argc != 1) {
  60.             napi_throw_error(env, nullptr, "Store args number must be one.");
  61.             return nullptr;
  62.         }
  63.         napi_valuetype type = napi_undefined;
  64.         napi_typeof(env, args[0], &type);
  65.         if (type != napi_number) {
  66.             napi_throw_error(env, nullptr, "Store args is not number.");
  67.             return nullptr;
  68.         }
  69.         if (thisVar == nullptr) {
  70.             return nullptr;
  71.         }
  72.         uint32_t value = 0;
  73.         napi_get_value_uint32(env, args[0], &value);
  74.         void* object = nullptr;
  75.         napi_unwrap(env, thisVar, &object);
  76.         if (object == nullptr) {
  77.             return nullptr;
  78.         }
  79.         std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
  80.         reinterpret_cast<Object *>(object)-> numberSet_.insert(value);
  81.         return nullptr;
  82.     }
  83.     // 删除数组元素
  84.     static napi_value Erase(napi_env env, napi_callback_info info)
  85.     {
  86.         size_t argc = 1;
  87.         napi_value args[1] = {nullptr};
  88.         napi_value thisVar = nullptr;
  89.         napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
  90.         if (argc != 1) {
  91.             napi_throw_error(env, nullptr, "Erase args number must be one.");
  92.             return nullptr;
  93.         }
  94.         napi_valuetype type = napi_undefined;
  95.         napi_typeof(env, args[0], &type);
  96.         if (type != napi_number) {
  97.             napi_throw_error(env, nullptr, "Erase args is not number.");
  98.             return nullptr;
  99.         }
  100.         if (thisVar == nullptr) {
  101.             return nullptr;
  102.         }
  103.         uint32_t value = 0;
  104.         napi_get_value_uint32(env, args[0], &value);
  105.         void* object = nullptr;
  106.         napi_unwrap(env, thisVar, &object);
  107.         if (object == nullptr) {
  108.             return nullptr;
  109.         }
  110.         std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
  111.         reinterpret_cast<Object *>(object)->numberSet_.erase(value);
  112.         return nullptr;
  113.     }
  114.     // 清空数组
  115.     static napi_value Clear(napi_env env, napi_callback_info info)
  116.     {
  117.         napi_value thisVar = nullptr;
  118.         napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
  119.         if (thisVar == nullptr) {
  120.             return nullptr;
  121.         }
  122.         void* object = nullptr;
  123.         napi_unwrap(env, thisVar, &object);
  124.         if (object == nullptr) {
  125.             return nullptr;
  126.         }
  127.         std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
  128.         reinterpret_cast<Object *>(object)->numberSet_.clear();
  129.         return nullptr;
  130.     }
  131. private:
  132.     Object(const Object &) = delete;
  133.     Object &operator=(const Object &) = delete;
  134.     std::unordered_set<uint32_t> numberSet_{};
  135.     std::mutex numberSetMutex_{};
  136. };
  137. void FinializerCallback(napi_env env, void *data, void *hint)
  138. {
  139.     return;
  140. }
  141. // 解绑回调,在序列化时调用,可在对象解绑时执行一些清理操作
  142. void* DetachCallback(napi_env env, void *value, void *hint)
  143. {
  144.     return value;
  145. }
  146. // 绑定回调,在反序列化时调用
  147. napi_value AttachCallback(napi_env env, void* value, void* hint)
  148. {
  149.     napi_value object = nullptr;
  150.     napi_create_object(env, &object);
  151.     napi_property_descriptor desc[] = {
  152.         {"getAddress", nullptr, Object::GetAddress, nullptr, nullptr, nullptr, napi_default, nullptr},
  153.         {"getSetSize", nullptr, Object::GetSetSize, nullptr, nullptr, nullptr, napi_default, nullptr},
  154.         {"store", nullptr, Object::Store, nullptr, nullptr, nullptr, napi_default, nullptr},
  155.         {"erase", nullptr, Object::Erase, nullptr, nullptr, nullptr, napi_default, nullptr},
  156.         {"clear", nullptr, Object::Clear, nullptr, nullptr, nullptr, napi_default, nullptr}};
  157.     napi_define_properties(env, object, sizeof(desc) / sizeof(desc[0]), desc);
  158.     // 将JS对象object和native对象value生命周期进行绑定
  159.     napi_status status = napi_wrap(env, object, value, FinializerCallback, nullptr, nullptr);
  160.     if (status != napi_ok) {
  161.         OH_LOG_INFO(LOG_APP, "Node-API attachCallback is failed.");
  162.     }
  163.     // JS对象携带native信息
  164.     napi_coerce_to_native_binding_object(env, object, DetachCallback, AttachCallback, value, hint);
  165.     return object;
  166. }
  167. EXTERN_C_START
  168. static napi_value Init(napi_env env, napi_value exports)
  169. {
  170.     napi_property_descriptor desc[] = {
  171.         {"getAddress", nullptr, Object::GetAddress, nullptr, nullptr, nullptr, napi_default, nullptr},
  172.         {"getSetSize", nullptr, Object::GetSetSize, nullptr, nullptr, nullptr, napi_default, nullptr},
  173.         {"store", nullptr, Object::Store, nullptr, nullptr, nullptr, napi_default, nullptr},
  174.         {"erase", nullptr, Object::Erase, nullptr, nullptr, nullptr, napi_default, nullptr},
  175.         {"clear", nullptr, Object::Clear, nullptr, nullptr, nullptr, napi_default, nullptr}};
  176.     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  177.     auto object = Object::GetInstance();
  178.     napi_status status = napi_wrap(env, exports, reinterpret_cast<void*>(object), FinializerCallback, nullptr, nullptr);
  179.     if (status != napi_ok) {
  180.         delete object;
  181.     }
  182.     napi_coerce_to_native_binding_object(env, exports, DetachCallback, AttachCallback, reinterpret_cast<void*>(object),
  183.                                          nullptr);
  184.     return exports;
  185. }
  186. EXTERN_C_END
  187. static napi_module demoModule = {
  188.     .nm_version = 1,
  189.     .nm_flags = 0,
  190.     .nm_filename = nullptr,
  191.     .nm_register_func = Init,
  192.     .nm_modname = "entry",
  193.     .nm_priv = ((void*)0),
  194.     .reserved = { 0 },
  195. };
  196. extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
  197. {
  198.     napi_module_register(&demoModule);
  199. }
  200. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const getAddress: () => number;
  3. export const getSetSize: () => number;
  4. export const store: (a: number) => void;
  5. export const erase: (a: number) => void;
  6. export const clear: () => void;
  7. ts
复制代码
ArkTS侧示例代码
  1. // index.ets
  2. import testNapi from 'libentry.so';
  3. import taskpool from '@ohos.taskpool';
  4. @Concurrent
  5. function getAddress() {
  6.   let address: number = testNapi.getAddress();
  7.   console.info("taskpool:: address is " + address);
  8. }
  9. @Concurrent
  10. function store(a:number, b:number, c:number) {
  11.   let size:number = testNapi.getSetSize();
  12.   console.info("set size is " + size + " before store");
  13.   testNapi.store(a);
  14.   testNapi.store(b);
  15.   testNapi.store(c);
  16.   size = testNapi.getSetSize();
  17.   console.info("set size is " + size + " after store");
  18. }
  19. @Concurrent
  20. function erase(a:number) {
  21.   let size:number = testNapi.getSetSize();
  22.   console.info("set size is " + size + " before erase");
  23.   testNapi.erase(a);
  24.   size = testNapi.getSetSize();
  25.   console.info("set size is " + size + " after erase");
  26. }
  27. @Concurrent
  28. function clear() {
  29.   let size:number = testNapi.getSetSize();
  30.   console.info("set size is " + size + " before clear");
  31.   testNapi.clear();
  32.   size = testNapi.getSetSize();
  33.   console.info("set size is " + size + " after clear");
  34. }
  35. async function test01(): Promise<void> {
  36.     let address:number = testNapi.getAddress();
  37.     console.info("host thread address is " + address);
  38.     let task1 = new taskpool.Task(getAddress);
  39.     await taskpool.execute(task1);
  40.     let task2 = new taskpool.Task(store, 1, 2, 3);
  41.     await taskpool.execute(task2);
  42.     let task3 = new taskpool.Task(store, 4, 5, 6);
  43.     await taskpool.execute(task3);
  44.     let task4 = new taskpool.Task(erase, 3);
  45.     await taskpool.execute(task4);
  46.     let task5 = new taskpool.Task(erase, 5);
  47.     await taskpool.execute(task5);
  48.     let task6 = new taskpool.Task(clear);
  49.     await taskpool.execute(task6);
  50. }
  51. test01();
  52. ts
复制代码
注意事项
对ArkTs对象A调用napi_coerce_to_native_binding_object将开发者实现的detach/attach回调和native对象信息加到A上,再将A跨线程传递。跨线程传递需要对A进行序列化和反序列化,在当火线程thread1序列化A得到数据data,序列化阶段执行detach回调。然后将data传给目标线程thread2,在thread2中反序列化data,执行attach回调,最终得到ArkTS对象A。

事件循环

接口描述

接口描述napi_run_event_loop触发底层的事件循环。napi_stop_event_loop停止底层的事件循环。 利用示例

napi_run_event_loop、napi_stop_event_loop

ArkTS基础运行时情况

接口描述

接口描述napi_create_ark_runtime创建基础运行时情况。napi_destroy_ark_runtime销毁基础运行时情况。 利用示例

napi_create_ark_runtime、napi_destroy_ark_runtime

序列化和反序列化

接口描述

接口描述napi_serialize将ArkTS对象转换为native数据。第一个参数env是接口执行的ArkTS情况;第二个参数object是待序列化的ArkTS对象;第三个参数transfer_list是存放需要以transfer传递的arrayBuffer的array,如不涉及可传undefined;第四个参数clone_list是存放需要克隆传递的Sendable对象的array,如不涉及可传undefined;第五个参数result是序列化结果。napi_deserialize将native数据转为ArkTS对象。第一个参数env是接口执行的ArkTS情况;第二个参数buffer是序列化数据;第三个参数object是反序列化得到的结果。napi_delete_serialization_data删除序列化数据。 利用示例

napi_serialize、napi_deserialize、napi_delete_serialization_data

用于将ArkTS对象转换为native数据、将native数据转为ArkTS对象、删除序列化数据等操作。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value AboutSerialize(napi_env env, napi_callback_info info)
  3. {
  4.     // 获取传入的ts的一个对象作为参数
  5.     size_t argc = 1;
  6.     napi_value args[1] = {nullptr};
  7.     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  8.     napi_value undefined = nullptr;
  9.     // 构造napi_serialize方法所需参数
  10.     napi_get_undefined(env, &undefined);
  11.     void *data = nullptr;
  12.     // 调用napi_serialize方法将ts对象转化为native数据
  13.     napi_status status = napi_serialize(env, args[0], undefined, undefined, &data);
  14.     if (status != napi_ok ||data == nullptr) {
  15.         napi_throw_error(env, nullptr, "Node-API napi_serialize fail");
  16.         return nullptr;
  17.     }
  18.     // 构造napi_value类型的数据,用于接收将native数据转化为ts对象后的数据
  19.     napi_value result = nullptr;
  20.     napi_deserialize(env, data, &result);
  21.     napi_value number = nullptr;
  22.     // 获取native数据转化为ts对象后的数据中的numKey属性的值
  23.     napi_get_named_property(env, result, "numKey", &number);
  24.     // 判断获取到的属性值是否为number类型
  25.     napi_valuetype valuetype;
  26.     napi_typeof(env, number, &valuetype);
  27.     if (valuetype != napi_number) {
  28.         napi_throw_error(env, nullptr, "Node-API Wrong type of argument. Expects a number.");
  29.         return nullptr;
  30.     }
  31.     // 调用napi_delete_serialization_data方法删除序列化数据
  32.     napi_delete_serialization_data(env, data);
  33.     // 返回获取到的属性值
  34.     return number;
  35. }
  36. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const aboutSerialize: (obj: Object) => number;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. class Obj {
  4.   numKey:number = 0;
  5. }
  6. let obj: Obj = { numKey: 500 };
  7. hilog.info(0x0000, 'testTag', ' Node-API aboutSerialize: %{public}d', testNapi.aboutSerialize(obj));
  8. ts
复制代码
根据使命指定的优先级和入队方式进行处理惩罚异步线程向ArkTS线程投递的使命

接口描述

接口描述napi_call_threadsafe_function_with_priority将指定优先级和入队方式的使命投递到ArkTS主线程。 利用示例

napi_call_threadsafe_function_with_priority

Sendable相干

接口描述

接口描述napi_is_sendable判定给定ArkTS value是否是Sendable的。napi_define_sendable_class创建一个sendable类。napi_create_sendable_object_with_properties利用给定的napi_property_descriptor创建一个sendable对象。napi_create_sendable_array创建一个sendable数组。napi_create_sendable_array_with_length创建一个指定长度的sendable数组。napi_create_sendable_arraybuffer创建一个sendable ArrayBuffer。napi_create_sendable_typedarray创建一个sendable TypedArray。napi_wrap_sendable包裹一个native实例到ArkTS对象中。napi_wrap_sendable_with_size包裹一个native实例到ArkTS对象中并指定大小。napi_unwrap_sendable获取ArkTS对象包裹的native实例。napi_remove_wrap_sendable移除并获取ArkTS对象包裹的native实例。 利用示例

napi_is_sendable

判定给定ArkTS value是否是Sendable的。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value IsSendable(napi_env env, napi_callback_info info) {
  3.     size_t argc = 1;
  4.     napi_value args[1] = {nullptr};
  5.     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  6.     bool isSendable = false;
  7.     napi_is_sendable(env, args[0], &isSendable);
  8.     napi_value result;
  9.     napi_get_boolean(env, isSendable, &result);
  10.     return result;
  11. }
  12. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const isSendable: <T>(a: T) => boolean;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = testNapi.isSendable('createObject');
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_is_sendable: %{public}s', JSON.stringify(value));
  5. ts
复制代码
napi_define_sendable_class

创建一个sendable类。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value func(napi_env env, napi_callback_info info) {
  3.     napi_value val;
  4.     napi_create_string_utf8(env, "func result", NAPI_AUTO_LENGTH, &val);
  5.     return val;
  6. }
  7. static napi_value DefineSendableClass(napi_env env) {
  8.     napi_value str;
  9.     napi_create_string_utf8(env, "str", NAPI_AUTO_LENGTH, &str);
  10.     napi_property_descriptor props[] = {
  11.         {"staticStr", nullptr, nullptr, nullptr, nullptr, str,
  12.          static_cast<napi_property_attributes>(napi_static | napi_writable), nullptr},
  13.         {"staticFunc", nullptr, func, nullptr, nullptr, nullptr, napi_static, nullptr},
  14.         {"str", nullptr, nullptr, nullptr, nullptr, str, static_cast<napi_property_attributes>(1 << 9 | napi_writable),
  15.          nullptr},
  16.         {"func", nullptr, nullptr, nullptr, nullptr, nullptr,
  17.          static_cast<napi_property_attributes>(1 << 11 | napi_writable), nullptr},
  18.     };
  19.     napi_value sendableClass = nullptr;
  20.     napi_define_sendable_class(
  21.         env, "SendableClass", NAPI_AUTO_LENGTH,
  22.         [](napi_env env, napi_callback_info info) -> napi_value {
  23.             napi_value thisVar = nullptr;
  24.             napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
  25.             napi_value str;
  26.             napi_create_string_utf8(env, "instance str", NAPI_AUTO_LENGTH, &str);
  27.             napi_property_descriptor props[] = {
  28.                 {"str", nullptr, nullptr, nullptr, nullptr, str, napi_default, nullptr},
  29.                 {"func", nullptr, func, nullptr, nullptr, nullptr, napi_default, nullptr},
  30.             };
  31.             napi_define_properties(env, thisVar, sizeof(props) / sizeof(props[0]), props);
  32.             return thisVar;
  33.         },
  34.         nullptr, sizeof(props) / sizeof(props[0]), props, nullptr, &sendableClass);
  35.     return sendableClass;
  36. }
  37. EXTERN_C_START
  38. static napi_value Init(napi_env env, napi_value exports)
  39. {
  40.     napi_property_descriptor desc[] = {};
  41.     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  42.     napi_value cons = DefineSendableClass(env);
  43.     napi_set_named_property(env, exports, "SendableClass", cons);
  44.     return exports;
  45. }
  46. EXTERN_C_END
  47. static napi_module demoModule = {
  48.     .nm_version = 1,
  49.     .nm_flags = 0,
  50.     .nm_filename = nullptr,
  51.     .nm_register_func = Init,
  52.     .nm_modname = "entry",
  53.     .nm_priv = ((void*)0),
  54.     .reserved = { 0 },
  55. };
  56. extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
  57. {
  58.     napi_module_register(&demoModule);
  59. }
  60. cpp
复制代码
接口声明
  1. // index.d.ts
  2. @Sendable
  3. export class SendableClass {
  4.   static staticStr: string;
  5.   static staticFunc(): string;
  6.   str: string;
  7.   func(): string;
  8. }
  9. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = new testNapi.SendableClass();
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_define_sendable_class: %{public}s', value.str);
  5. ts
复制代码
napi_create_sendable_object_with_properties

利用给定的napi_property_descriptor创建一个sendable对象。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value GetSendableObject(napi_env env, napi_callback_info info) {
  3.     napi_value val_true;
  4.     napi_get_boolean(env, true, &val_true);
  5.     napi_property_descriptor desc1[] = {
  6.         {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
  7.     };
  8.     napi_value obj;
  9.     napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
  10.     return obj;
  11. }
  12. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const getSendableObject: () => { x: true };
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = testNapi.getSendableObject();
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_object_with_properties: %{public}s', JSON.stringify(value));
  5. ts
复制代码
napi_create_sendable_array

创建一个sendable数组。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value GetSendableArray(napi_env env, napi_callback_info info) {
  3.     napi_value result = nullptr;
  4.     napi_create_sendable_array(env, &result);
  5.     return result;
  6. }
  7. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const getSendableArray: () => [];
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = testNapi.getSendableArray();
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_array: %{public}s', JSON.stringify(value));
  5. ts
复制代码
napi_create_sendable_array_with_length

创建一个指定长度的sendable数组。
cpp部分代码
  1. static napi_value GetSendableArrayWithLength(napi_env env, napi_callback_info info) {
  2.     napi_value result = nullptr;
  3.     napi_create_sendable_array_with_length(env, 1, &result);
  4.     return result;
  5. }
  6. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const getSendableArrayWithLength: () => [];
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. let value = testNapi.getSendableArrayWithLength();
  4. hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_array_with_length: %{public}s', JSON.stringify(value.length));
  5. ts
复制代码
napi_create_sendable_arraybuffer

创建一个sendable ArrayBuffer。
cpp部分代码
  1. #include "napi/native_api.h"
  2. #include "hilog/log.h"
  3. static napi_value GetSendableArrayBuffer(napi_env env, napi_callback_info info) {
  4.     static size_t LENGTH = 1024;
  5.     void *data;
  6.     napi_value result = nullptr;
  7.     napi_create_sendable_arraybuffer(env, LENGTH, &data, &result);
  8.     bool isArrayBuffer = false;
  9.     napi_is_arraybuffer(env, result, &isArrayBuffer);
  10.     OH_LOG_INFO(LOG_APP, "isArrayBuffer: %{public}d", isArrayBuffer);
  11.     return result;
  12. }
  13. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const getSendableArrayBuffer: () => void;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. testNapi.getSendableArrayBuffer();
  4. ts
复制代码
napi_create_sendable_typedarray

创建一个sendable TypedArray。
cpp部分代码
  1. #include "napi/native_api.h"
  2. #include "hilog/log.h"
  3. static napi_value GetSendableTypedArray(napi_env env, napi_callback_info info) {
  4.     static size_t LENGTH = 1024;
  5.     static size_t OFFSET = 0;
  6.     void *data;
  7.     napi_value arraybuffer = nullptr;
  8.     napi_create_sendable_arraybuffer(env, LENGTH, &data, &arraybuffer);
  9.     napi_value result = nullptr;
  10.     napi_create_sendable_typedarray(env, napi_uint8_array, LENGTH, arraybuffer, OFFSET, &result);
  11.     bool isTypedArray = false;
  12.     napi_is_typedarray(env, result, &isTypedArray);
  13.     OH_LOG_INFO(LOG_APP, "isTypedArray: %{public}d", isTypedArray);
  14.     return result;
  15. }
  16. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const getSendableTypedArray: () => void;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. testNapi.getSendableTypedArray();
  4. ts
复制代码
napi_wrap_sendable

包裹一个native实例到ArkTS对象中。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value WrapSendable(napi_env env, napi_callback_info info) {
  3.     napi_value val_true;
  4.     napi_get_boolean(env, true, &val_true);
  5.     napi_property_descriptor desc1[] = {
  6.         {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
  7.     };
  8.     napi_value obj;
  9.     napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
  10.     const char* testStr = "test";
  11.     napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
  12.     return nullptr;
  13. }
  14. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const wrapSendable: () => void;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. testNapi.wrapSendable();
  4. ts
复制代码
napi_wrap_sendable_with_size

包裹一个native实例到ArkTS对象中并指定大小。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value WrapSendableWithSize(napi_env env, napi_callback_info info) {
  3.     napi_value val_true;
  4.     napi_get_boolean(env, true, &val_true);
  5.     napi_property_descriptor desc1[] = {
  6.         {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
  7.     };
  8.     napi_value obj;
  9.     napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
  10.     const char* testStr = "test";
  11.     napi_wrap_sendable_with_size(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr, 100);
  12.     return nullptr;
  13. }
  14. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const wrapSendableWithSize: () => void;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. testNapi.wrapSendableWithSize();
  4. ts
复制代码
napi_unwrap_sendable

获取ArkTS对象包裹的native实例。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value UnwrapSendable(napi_env env, napi_callback_info info) {
  3.     napi_value val_true;
  4.     napi_get_boolean(env, true, &val_true);
  5.     napi_property_descriptor desc1[] = {
  6.         {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
  7.     };
  8.     napi_value obj;
  9.     napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
  10.     const char* testStr = "test";
  11.     napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
  12.     char* tmpTestStr = nullptr;
  13.     napi_unwrap_sendable(env, obj, (void**)&tmpTestStr);
  14.     OH_LOG_INFO(LOG_APP, "native value is %{public}s", tmpTestStr);
  15.     return nullptr;
  16. }
  17. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const unwrapSendable: () => void;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. testNapi.unwrapSendable();
  4. ts
复制代码
napi_remove_wrap_sendable

移除并获取ArkTS对象包裹的native实例。
cpp部分代码
  1. #include "napi/native_api.h"
  2. static napi_value RemoveWrapSendable(napi_env env, napi_callback_info info) {
  3.     napi_value val_true;
  4.     napi_get_boolean(env, true, &val_true);
  5.     napi_property_descriptor desc1[] = {
  6.         {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
  7.     };
  8.     napi_value obj;
  9.     napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
  10.     const char* testStr = "test";
  11.     napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
  12.     char* tmpTestStr = nullptr;
  13.     napi_remove_wrap_sendable(env, obj, (void**)&tmpTestStr);
  14.     OH_LOG_INFO(LOG_APP, "native value is %{public}s", tmpTestStr);
  15.     return nullptr;
  16. }
  17. cpp
复制代码
接口声明
  1. // index.d.ts
  2. export const removeWrapSendable: () => void;
  3. ts
复制代码
ArkTS侧示例代码
  1. import hilog from '@ohos.hilog'
  2. import testNapi from 'libentry.so'
  3. testNapi.removeWrapSendable();
  4. ts
复制代码
以上代码假如要在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)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表