• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用Node-API扩展能力接口
2<!--Kit: NDK-->
3<!--Subsystem: arkcompiler-->
4<!--Owner: @xliu-huanwei; @shilei123; @huanghello-->
5<!--Designer: @shilei123-->
6<!--Tester: @kirl75; @zsw_zhushiwei-->
7<!--Adviser: @fang-jinxu-->
8
9## 简介
10
11[扩展能力](napi-data-types-interfaces.md#扩展能力)接口进一步扩展了Node-API的功能,提供了一些额外的接口,用于在Node-API模块中与ArkTS进行更灵活的交互和定制,这些接口可以用于创建自定义ArkTS对象等场景。
12
13Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
14
15## 模块加载
16
17### 接口描述
18
19| 接口 | 描述 |
20| -------- | -------- |
21| napi_load_module | 用于在Node-API模块中将abc文件作为模块加载,返回模块的命名空间,适用于需要在运行时动态加载模块或资源的应用程序,从而实现灵活的扩展和定制。 |
22| napi_load_module_with_info | 用于在Node-API中进行模块的加载,当模块加载出来之后,可以使用函数napi_get_property获取模块导出的变量,也可以使用napi_get_named_property获取模块导出的函数,该函数可以在[新创建的ArkTS基础运行时环境](use-napi-ark-runtime.md)中使用。 |
23| napi_module_register | 有些功能可能需要通过Node-API模块来实现以获得更好的性能,通过将这些功能实现为自定义模块并注册到ArkTS环境中,可以在一定程度上提高整体的性能。 |
24
25### 使用示例
26
27**napi_load_module**
28
29[使用Node-API接口在主线程中进行模块加载](use-napi-load-module.md)
30
31**napi_load_module_with_info**
32
33[使用Node-API接口进行模块加载](use-napi-load-module-with-info.md)
34
35**napi_module_register**
36
37在ArkTS代码环境中使用Node-API模块编写的代码来实现特定的功能,可以将这部分功能封装成自定义模块,然后通过napi_module_register将其注册到ArkTS代码环境中,以实现功能的扩展和复用。
38
39cpp部分代码
40
41```cpp
42#include "napi/native_api.h"
43
44// 此模块是一个Node-API的回调函数
45static napi_value Add(napi_env env, napi_callback_info info)
46{
47    // 接受传入两个参数
48    size_t requireArgc = 2;
49    size_t argc = 2;
50    napi_value args[2] = {nullptr};
51    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
52
53    // 将传入的napi_value类型的参数转化为double类型
54    double valueLeft;
55    double valueRight;
56    napi_get_value_double(env, args[0], &valueLeft);
57    napi_get_value_double(env, args[1], &valueRight);
58
59    // 将转化后的double值相加并转成napi_value返回给ArkTS代码使用
60    napi_value sum;
61    napi_create_double(env, valueLeft + valueRight, &sum);
62
63    return sum;
64}
65
66// C++函数Init用于初始化插件,用于将ArkTS层的函数或属性与C++层的函数进行关联
67EXTERN_C_START
68static napi_value Init(napi_env env, napi_value exports)
69{
70    // 通过napi_property_descriptor结构体,可以定义需要导出的属性,并在Node-API模块中使用。napi_define_properties将属性与实际的C++函数进行关联,使其可以被ArkTS层访问和调用
71    napi_property_descriptor desc[] = {
72        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
73    };
74    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
75    return exports;
76}
77EXTERN_C_END
78
79// 插件的初始化被定义在一个名为demoModule的结构体中,其中包含了模块的基本信息,比如模块的版本号、注册函数等
80static napi_module demoModule = {
81    .nm_version =1,
82    .nm_flags = 0,
83    .nm_filename = nullptr,
84    .nm_register_func = Init,
85    .nm_modname = "entry",
86    .nm_priv = ((void*)0),
87    .reserved = { 0 },
88};
89
90// 在RegisterEntryModule函数中,使用napi_module_register函数注册并导出了这个插件
91extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
92{
93    napi_module_register(&demoModule);
94}
95```
96<!-- @[node_api_module_add](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
97
98接口声明
99
100```ts
101// index.d.ts
102export const add: (a: number, b: number) => number;
103```
104<!-- @[node_api_module_add_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
105
106ArkTS侧示例代码
107
108```ts
109import hilog from '@ohos.hilog';
110import testNapi from 'libentry.so';
111
112hilog.info(0x0000, 'testTag', 'Test Node-API 2 + 3 = %{public}d', testNapi.add(2, 3));
113```
114<!-- @[ark_node_api_module_add](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
115
116## ArkTS Object相关
117
118### 接口描述
119
120| 接口 | 描述 |
121| -------- | -------- |
122| napi_create_object_with_properties | 用于在Node-API模块中使用给定的napi_property_descriptor创建ArkTS Object。descriptor的键名必须为string,且不可转为number。 |
123| napi_create_object_with_named_properties | 用于在Node-API模块中使用给定的napi_value和键名创建ArkTS Object。键名必须为string,且不可转为number。 |
124
125### 使用示例
126
127**napi_create_object_with_properties**
128
129用给定的napi_property_descriptor作为属性去创建一个ArkTS对象,并且descriptor的键名必须为string,且不可转为number。
130
131cpp部分代码
132
133```cpp
134#include "napi/native_api.h"
135
136static napi_value CreateObjectWithProperties(napi_env env, napi_callback_info info)
137{
138    size_t argc = 1;
139    napi_value argv[1] = {nullptr};
140    // 获取解析传递的参数
141    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
142    // 声明了一个napi_property_descriptor数组desc,其中包含了一个名为"name"的属性,其值为传入的第一个参数argv[0]。
143    napi_property_descriptor desc[] = {
144        {"name", nullptr, nullptr, nullptr, nullptr, argv[0], napi_default_jsproperty, nullptr}};
145    napi_value object = nullptr;
146    // 调用napi_create_object_with_properties来创建一个新的ArkTS对象,并将属性值添加到该对象中。
147    napi_create_object_with_properties(env, &object, sizeof(desc) / sizeof(desc[0]), desc);
148    napi_valuetype valueType;
149    napi_typeof(env, object, &valueType);
150    if (valueType == napi_object) {
151        return object;
152    }
153}
154```
155<!-- @[node_api_module_create_object_properties](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
156
157接口声明
158
159```ts
160// index.d.ts
161export const createObjectWithProperties: (data: string) => Object;
162```
163<!-- @[node_api_module_create_object_properties_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
164
165ArkTS侧示例代码
166
167```ts
168import hilog from '@ohos.hilog';
169import testNapi from 'libentry.so';
170
171let value = testNapi.createObjectWithProperties('createObject');
172hilog.info(0x0000, 'testTag', 'Node-API napi_create_object_with_properties:%{public}s', JSON.stringify(value));
173```
174<!-- @[ark_node_api_module_create_object_properties](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
175
176**napi_create_object_with_named_properties**
177
178用于使用给定的napi_value和键名创建一个ArkTS对象,并且给定的键名必须为string,且不可转为number。
179
180cpp部分代码
181
182```cpp
183#include "napi/native_api.h"
184
185static napi_value CreateObjectWithNameProperties(napi_env env, napi_callback_info info)
186{
187    size_t argc = 1;
188    napi_value argv[1] = {nullptr};
189    // 获取解析传递的参数
190    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
191    napi_value obj = nullptr;
192    const char *key[] = {
193        "name",
194    };
195    const napi_value values[] = {
196        argv[0],
197    };
198    napi_property_descriptor desc[] = {{"name", nullptr, nullptr,
199                                        nullptr, nullptr, nullptr, napi_default, nullptr}};
200    napi_status status;
201    status = napi_create_object_with_named_properties(env, &obj, sizeof(desc) / sizeof(desc[0]), key, values);
202    if (status != napi_ok) {
203        return argv[0];
204    }
205    return obj;
206}
207```
208<!-- @[node_api_module_create_object_name_properties](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
209
210接口声明
211
212```ts
213// index.d.ts
214export const createObjectWithNameProperties: (data: string) => string | { name: string };
215```
216<!-- @[node_api_module_create_object_name_properties_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
217
218ArkTS侧示例代码
219
220```ts
221import hilog from '@ohos.hilog';
222import testNapi from 'libentry.so';
223
224let value = testNapi.createObjectWithNameProperties('ls');
225hilog.info(0x0000, 'testTag', 'Node-API napi_create_object_with_named_properties:%{public}s', JSON.stringify(value));
226```
227<!-- @[ark_node_api_module_create_object_name_properties](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
228
229## 运行指定abc文件
230
231### 接口描述
232
233| 接口 | 描述 |
234| -------- | -------- |
235| napi_run_script_path | 用于在Node-API模块中运行指定abc文件。 |
236
237### 使用示例
238
239**napi_run_script_path**
240
241在Node-API模块中运行abc文件。
242
243cpp部分代码
244
245```cpp
246#include "napi/native_api.h"
247
248static napi_value RunScriptPath(napi_env env, napi_callback_info info)
249{
250    napi_value value = nullptr;
251    // 注意:记得在应用rawfile目录下放置.abc文件
252    const char *scriptPath = "/entry/resources/rawfile/test.abc";
253    // 使用napi_run_script_path函数执行指定路径中的文件
254    napi_status status = napi_run_script_path(env, scriptPath, &value);
255    // 检查是否执行成功,如果失败,返回false
256    napi_value returnValue = nullptr;
257    if (value == nullptr || status != napi_ok) {
258        napi_get_boolean(env, false, &returnValue);
259    } else {
260        napi_get_boolean(env, true, &returnValue);
261    }
262    return returnValue;
263}
264```
265<!-- @[node_api_module_run_script_path](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
266
267接口声明
268
269```ts
270// index.d.ts
271export const runScriptPath: () => boolean;
272```
273<!-- @[node_api_module_run_script_path_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
274
275ArkTS侧示例代码
276
277```ts
278import hilog from '@ohos.hilog';
279import testNapi from 'libentry.so';
280
281try {
282  // 在此处执行错误返回false,成功就返回true
283  hilog.info(0x0000, 'testTag', 'Test Node-API napi_run_script_path: %{public}s', testNapi.runScriptPath());
284} catch (error) {
285  hilog.error(0x0000, 'testTag', 'Test Node-API napi_run_script_path errorMessage: %{public}s', error.message);
286}
287```
288<!-- @[ark_node_api_module_run_script_path](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
289
290test.js代码,将js代码编成.abc文件,步骤如下:
291
2921. 在SDK的ets/build-tools/ets-loader/bin/ark/build-win/bin目录下放置test.js文件
2932. 执行命令如es2abc.exe test.js  --output test.abc后便可生成test.abc文件
294
295放入指定路径中:/entry/resources/rawfile
296
297```js
298function add(a, b) {
299  return a+b;
300}
301add(1, 2);
302```
303
304## 异步工作对象加入队列并指定优先级
305
306### 接口描述
307
308| 接口 | 描述 |
309| -------- | -------- |
310| napi_queue_async_work_with_qos | 用于将异步工作对象加入队列,让开发者能够根据QoS优先级来管理和调度异步工作的执行,从而更好地满足程序的性能和响应需求。 |
311
312### 使用示例
313
314**napi_queue_async_work_with_qos**
315
316将异步工作对象加到队列,由底层根据传入的qos优先级去调度执行。
317
318<!--Del-->
319[指定异步任务调度优先级](../performance/develop-Native-modules-using-NAPI-safely-and-efficiently.md#指定异步任务调度优先级)
320<!--DelEnd-->
321
322## 给ArkTS对象绑定回调和回调所需的参数
323
324### 接口描述
325
326| 接口 | 描述 |
327| -------- | -------- |
328| napi_coerce_to_native_binding_object | 用于给ArkTS对象绑定回调和回调所需的参数,其作用是为了给ArkTS对象携带Native信息。 |
329
330### 使用示例
331
332**napi_coerce_to_native_binding_object**
333
334用于给ArkTS Object绑定回调和回调所需的参数,给ArkTS Object携带Native信息。
335
336cpp部分代码
337
338```cpp
339#include <hilog/log.h>
340#include <mutex>
341#include <unordered_set>
342#include "napi/native_api.h"
343
344class Object {
345public:
346    Object() = default;
347    ~Object() = default;
348
349    static Object* GetInstance()
350    {
351        Object* instance = new Object();
352        return instance;
353    }
354
355    static napi_value GetAddress(napi_env env, napi_callback_info info)
356    {
357        napi_value thisVar = nullptr;
358        napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
359        if (thisVar == nullptr) {
360            return nullptr;
361        }
362        void* object = nullptr;
363        napi_unwrap(env, thisVar, &object);
364        if (object == nullptr) {
365            return nullptr;
366        }
367        uint64_t addressVal = reinterpret_cast<uint64_t>(object);
368        napi_value address = nullptr;
369        napi_create_bigint_uint64(env, addressVal, &address);
370        return address;
371    }
372
373    // 获取数组大小
374    static napi_value GetSetSize(napi_env env, napi_callback_info info)
375    {
376        napi_value thisVar = nullptr;
377        napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
378        if (thisVar == nullptr) {
379            return nullptr;
380        }
381        void* object = nullptr;
382        napi_unwrap(env, thisVar, &object);
383        if (object == nullptr) {
384            return nullptr;
385        }
386        std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
387        uint32_t setSize = reinterpret_cast<Object*>(object)->numberSet_.size();
388        napi_value napiSize = nullptr;
389        napi_create_uint32(env, setSize, &napiSize);
390        return napiSize;
391    }
392
393    // 往数组里插入元素
394    static napi_value Store(napi_env env, napi_callback_info info)
395    {
396        size_t argc = 1;
397        napi_value args[1] = {nullptr};
398        napi_value thisVar = nullptr;
399        napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
400        if (argc != 1) {
401            napi_throw_error(env, nullptr, "Store args number must be one.");
402            return nullptr;
403        }
404        napi_valuetype type = napi_undefined;
405        napi_typeof(env, args[0], &type);
406        if (type != napi_number) {
407            napi_throw_error(env, nullptr, "Store args is not number.");
408            return nullptr;
409        }
410        if (thisVar == nullptr) {
411            return nullptr;
412        }
413        uint32_t value = 0;
414        napi_get_value_uint32(env, args[0], &value);
415        void* object = nullptr;
416        napi_unwrap(env, thisVar, &object);
417        if (object == nullptr) {
418            return nullptr;
419        }
420        std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
421        reinterpret_cast<Object *>(object)-> numberSet_.insert(value);
422        return nullptr;
423    }
424
425    // 删除数组元素
426    static napi_value Erase(napi_env env, napi_callback_info info)
427    {
428        size_t argc = 1;
429        napi_value args[1] = {nullptr};
430        napi_value thisVar = nullptr;
431        napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
432        if (argc != 1) {
433            napi_throw_error(env, nullptr, "Erase args number must be one.");
434            return nullptr;
435        }
436        napi_valuetype type = napi_undefined;
437        napi_typeof(env, args[0], &type);
438        if (type != napi_number) {
439            napi_throw_error(env, nullptr, "Erase args is not number.");
440            return nullptr;
441        }
442        if (thisVar == nullptr) {
443            return nullptr;
444        }
445        uint32_t value = 0;
446        napi_get_value_uint32(env, args[0], &value);
447        void* object = nullptr;
448        napi_unwrap(env, thisVar, &object);
449        if (object == nullptr) {
450            return nullptr;
451        }
452        std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
453        reinterpret_cast<Object *>(object)->numberSet_.erase(value);
454        return nullptr;
455    }
456
457    // 清空数组
458    static napi_value Clear(napi_env env, napi_callback_info info)
459    {
460        napi_value thisVar = nullptr;
461        napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
462        if (thisVar == nullptr) {
463            return nullptr;
464        }
465        void* object = nullptr;
466        napi_unwrap(env, thisVar, &object);
467        if (object == nullptr) {
468            return nullptr;
469        }
470        std::lock_guard<std::mutex> lock(reinterpret_cast<Object*>(object)->numberSetMutex_);
471        reinterpret_cast<Object *>(object)->numberSet_.clear();
472        return nullptr;
473    }
474
475private:
476    Object(const Object &) = delete;
477    Object &operator=(const Object &) = delete;
478
479    std::unordered_set<uint32_t> numberSet_{};
480    std::mutex numberSetMutex_{};
481};
482
483void FinializerCallback(napi_env env, void *data, void *hint)
484{
485    return;
486}
487
488// 解绑回调,在序列化时调用,可在对象解绑时执行一些清理操作
489void* DetachCallback(napi_env env, void *value, void *hint)
490{
491    return value;
492}
493
494// 绑定回调,在反序列化时调用
495napi_value AttachCallback(napi_env env, void* value, void* hint)
496{
497    napi_value object = nullptr;
498    napi_create_object(env, &object);
499    napi_property_descriptor desc[] = {
500        {"getAddress", nullptr, Object::GetAddress, nullptr, nullptr, nullptr, napi_default, nullptr},
501        {"getSetSize", nullptr, Object::GetSetSize, nullptr, nullptr, nullptr, napi_default, nullptr},
502        {"store", nullptr, Object::Store, nullptr, nullptr, nullptr, napi_default, nullptr},
503        {"erase", nullptr, Object::Erase, nullptr, nullptr, nullptr, napi_default, nullptr},
504        {"clear", nullptr, Object::Clear, nullptr, nullptr, nullptr, napi_default, nullptr}};
505    napi_define_properties(env, object, sizeof(desc) / sizeof(desc[0]), desc);
506    // 将JS对象object和native对象value生命周期进行绑定
507    napi_status status = napi_wrap(env, object, value, FinializerCallback, nullptr, nullptr);
508    if (status != napi_ok) {
509        OH_LOG_INFO(LOG_APP, "Node-API attachCallback is failed.");
510    }
511    // JS对象携带native信息
512    napi_coerce_to_native_binding_object(env, object, DetachCallback, AttachCallback, value, hint);
513    return object;
514}
515
516EXTERN_C_START
517static napi_value Init(napi_env env, napi_value exports)
518{
519    napi_property_descriptor desc[] = {
520        {"getAddress", nullptr, Object::GetAddress, nullptr, nullptr, nullptr, napi_default, nullptr},
521        {"getSetSize", nullptr, Object::GetSetSize, nullptr, nullptr, nullptr, napi_default, nullptr},
522        {"store", nullptr, Object::Store, nullptr, nullptr, nullptr, napi_default, nullptr},
523        {"erase", nullptr, Object::Erase, nullptr, nullptr, nullptr, napi_default, nullptr},
524        {"clear", nullptr, Object::Clear, nullptr, nullptr, nullptr, napi_default, nullptr}};
525    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
526    auto object = Object::GetInstance();
527    napi_status status = napi_wrap(env, exports, reinterpret_cast<void*>(object), FinializerCallback, nullptr, nullptr);
528    if (status != napi_ok) {
529        delete object;
530    }
531    napi_coerce_to_native_binding_object(env, exports, DetachCallback, AttachCallback, reinterpret_cast<void*>(object),
532                                         nullptr);
533    return exports;
534}
535EXTERN_C_END
536
537static napi_module demoModule = {
538    .nm_version = 1,
539    .nm_flags = 0,
540    .nm_filename = nullptr,
541    .nm_register_func = Init,
542    .nm_modname = "entry",
543    .nm_priv = ((void*)0),
544    .reserved = { 0 },
545};
546
547extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
548{
549    napi_module_register(&demoModule);
550}
551```
552<!-- @[napi_coerce_to_native_binding_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
553
554接口声明
555
556```ts
557// index.d.ts
558export const getAddress: () => number;
559export const getSetSize: () => number;
560export const store: (a: number) => void;
561export const erase: (a: number) => void;
562export const clear: () => void;
563```
564<!-- @[napi_coerce_to_native_binding_object_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
565
566ArkTS侧示例代码
567
568```ts
569// index.ets
570import testNapi from 'libentry.so';
571import taskpool from '@ohos.taskpool';
572
573@Concurrent
574function getAddress() {
575  let address: number = testNapi.getAddress();
576  console.info("taskpool:: address is " + address);
577}
578
579@Concurrent
580function store(a:number, b:number, c:number) {
581  let size:number = testNapi.getSetSize();
582  console.info("set size is " + size + " before store");
583  testNapi.store(a);
584  testNapi.store(b);
585  testNapi.store(c);
586  size = testNapi.getSetSize();
587  console.info("set size is " + size + " after store");
588}
589
590@Concurrent
591function erase(a:number) {
592  let size:number = testNapi.getSetSize();
593  console.info("set size is " + size + " before erase");
594  testNapi.erase(a);
595  size = testNapi.getSetSize();
596  console.info("set size is " + size + " after erase");
597}
598
599@Concurrent
600function clear() {
601  let size:number = testNapi.getSetSize();
602  console.info("set size is " + size + " before clear");
603  testNapi.clear();
604  size = testNapi.getSetSize();
605  console.info("set size is " + size + " after clear");
606}
607
608async function test01(): Promise<void> {
609    let address:number = testNapi.getAddress();
610    console.info("host thread address is " + address);
611
612    let task1 = new taskpool.Task(getAddress);
613    await taskpool.execute(task1);
614
615    let task2 = new taskpool.Task(store, 1, 2, 3);
616    await taskpool.execute(task2);
617
618    let task3 = new taskpool.Task(store, 4, 5, 6);
619    await taskpool.execute(task3);
620
621    let task4 = new taskpool.Task(erase, 3);
622    await taskpool.execute(task4);
623
624    let task5 = new taskpool.Task(erase, 5);
625    await taskpool.execute(task5);
626
627    let task6 = new taskpool.Task(clear);
628    await taskpool.execute(task6);
629}
630
631test01();
632```
633<!-- @[ark_napi_coerce_to_native_binding_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
634
635**注意事项**
636
637对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。
638
639![napi_coerce_to_native_binding_object](figures/napi_coerce_to_native_binding_object.png)
640
641## 事件循环
642
643### 接口描述
644
645| 接口 | 描述 |
646| -------- | -------- |
647| napi_run_event_loop | 触发底层的事件循环。 |
648| napi_stop_event_loop | 停止底层的事件循环。 |
649
650### 使用示例
651
652**napi_run_event_loop、napi_stop_event_loop**
653
654[使用扩展的Node-API接口在异步线程中运行和停止事件循环](use-napi-event-loop.md)
655
656## ArkTS基础运行时环境
657
658### 接口描述
659
660| 接口 | 描述 |
661| -------- | -------- |
662| napi_create_ark_runtime | 创建基础运行时环境。 |
663| napi_destroy_ark_runtime | 销毁基础运行时环境。 |
664
665### 使用示例
666
667**napi_create_ark_runtime、napi_destroy_ark_runtime**
668
669[使用Node-API接口创建ArkTS运行时环境](use-napi-ark-runtime.md)
670
671## 序列化和反序列化
672
673### 接口描述
674
675| 接口 | 描述 |
676| -------- | -------- |
677| napi_serialize | 将ArkTS对象转换为native数据。第一个参数env是接口执行的ArkTS环境;第二个参数object是待序列化的ArkTS对象;第三个参数transfer_list是存放需要以transfer传递的arrayBuffer的array,如不涉及可传undefined;第四个参数clone_list是存放需要克隆传递的Sendable对象的array,如不涉及可传undefined;第五个参数result是序列化结果。 |
678| napi_deserialize | 将native数据转为ArkTS对象。第一个参数env是接口执行的ArkTS环境;第二个参数buffer是序列化数据;第三个参数object是反序列化得到的结果。 |
679| napi_delete_serialization_data | 删除序列化数据。 |
680
681### 使用示例
682
683**napi_serialize、napi_deserialize、napi_delete_serialization_data**
684
685用于将ArkTS对象转换为native数据、将native数据转为ArkTS对象、删除序列化数据等操作。
686
687cpp部分代码
688
689```cpp
690#include "napi/native_api.h"
691
692static napi_value AboutSerialize(napi_env env, napi_callback_info info)
693{
694    // 获取传入的ts的一个对象作为参数
695    size_t argc = 1;
696    napi_value args[1] = {nullptr};
697    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
698    napi_value undefined = nullptr;
699    // 构造napi_serialize方法所需参数
700    napi_get_undefined(env, &undefined);
701    void *data = nullptr;
702    // 调用napi_serialize方法将ts对象转化为native数据
703    napi_status status = napi_serialize(env, args[0], undefined, undefined, &data);
704    if (status != napi_ok ||data == nullptr) {
705        napi_throw_error(env, nullptr, "Node-API napi_serialize fail");
706        return nullptr;
707    }
708    // 构造napi_value类型的数据,用于接收将native数据转化为ts对象后的数据
709    napi_value result = nullptr;
710    napi_deserialize(env, data, &result);
711    napi_value number = nullptr;
712    // 获取native数据转化为ts对象后的数据中的numKey属性的值
713    napi_get_named_property(env, result, "numKey", &number);
714    // 判断获取到的属性值是否为number类型
715    napi_valuetype valuetype;
716    napi_typeof(env, number, &valuetype);
717    if (valuetype != napi_number) {
718        napi_throw_error(env, nullptr, "Node-API Wrong type of argument. Expects a number.");
719        return nullptr;
720    }
721    // 调用napi_delete_serialization_data方法删除序列化数据
722    napi_delete_serialization_data(env, data);
723    // 返回获取到的属性值
724    return number;
725}
726```
727<!-- @[napi_serialize_deserialize_delete_serialization_data](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
728
729接口声明
730
731```ts
732// index.d.ts
733export const aboutSerialize: (obj: Object) => number;
734```
735<!-- @[napi_serialize_deserialize_delete_serialization_data_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
736
737ArkTS侧示例代码
738
739```ts
740import hilog from '@ohos.hilog';
741import testNapi from 'libentry.so';
742class Obj {
743  numKey:number = 0;
744}
745let obj: Obj = { numKey: 500 };
746hilog.info(0x0000, 'testTag', ' Node-API aboutSerialize: %{public}d', testNapi.aboutSerialize(obj));
747```
748<!-- @[ark_napi_serialize_deserialize_delete_serialization_data](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
749
750## 根据任务指定的优先级和入队方式进行处理异步线程向ArkTS线程投递的任务
751
752### 接口描述
753
754| 接口 | 描述 |
755| -------- | -------- |
756| napi_call_threadsafe_function_with_priority | 将指定优先级和入队方式的任务投递到ArkTS主线程。 |
757
758### 使用示例
759
760**napi_call_threadsafe_function_with_priority**
761
762[使用Node-API接口从异步线程向ArkTS线程投递指定优先级和入队方式的的任务](use-call-threadsafe-function-with-priority.md)
763
764## Sendable相关
765
766### 接口描述
767
768| 接口                       | 描述                               |
769| -------------------------- | ---------------------------------- |
770| napi_is_sendable           | 判断给定ArkTS value是否是Sendable的。 |
771| napi_define_sendable_class | 创建一个sendable类。               |
772| napi_create_sendable_object_with_properties | 使用给定的napi_property_descriptor创建一个sendable对象。|
773| napi_create_sendable_array | 创建一个sendable数组。|
774| napi_create_sendable_array_with_length | 创建一个指定长度的sendable数组。|
775| napi_create_sendable_arraybuffer | 创建一个sendable ArrayBuffer。|
776| napi_create_sendable_typedarray | 创建一个sendable TypedArray。|
777| napi_wrap_sendable | 包裹一个native实例到ArkTS对象中。|
778| napi_wrap_sendable_with_size | 包裹一个native实例到ArkTS对象中并指定大小。|
779| napi_unwrap_sendable | 获取ArkTS对象包裹的native实例。|
780| napi_remove_wrap_sendable | 移除并获取ArkTS对象包裹的native实例,移除后回调将不再触发,需手动delete释放内存。|
781
782### 使用示例
783
784**napi_is_sendable**
785
786判断给定ArkTS value是否是Sendable的。
787
788cpp部分代码
789
790```cpp
791#include "napi/native_api.h"
792
793static napi_value IsSendable(napi_env env, napi_callback_info info) {
794    size_t argc = 1;
795    napi_value args[1] = {nullptr};
796    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
797    bool isSendable = false;
798    napi_is_sendable(env, args[0], &isSendable);
799    napi_value result;
800    napi_get_boolean(env, isSendable, &result);
801    return result;
802}
803```
804<!-- @[napi_is_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
805
806接口声明
807
808```ts
809// index.d.ts
810export const isSendable: <T>(a: T) => boolean;
811```
812<!-- @[napi_is_sendable_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
813
814ArkTS侧示例代码
815
816```ts
817import hilog from '@ohos.hilog';
818import testNapi from 'libentry.so';
819
820let value = testNapi.isSendable('createObject');
821hilog.info(0x0000, 'testTag', 'Node-API napi_is_sendable: %{public}s', JSON.stringify(value));
822```
823<!-- @[ark_napi_is_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
824
825**napi_define_sendable_class**
826
827创建一个sendable类。
828
829cpp部分代码
830
831```cpp
832#include "napi/native_api.h"
833
834static napi_value func(napi_env env, napi_callback_info info) {
835    napi_value val;
836    napi_create_string_utf8(env, "func result", NAPI_AUTO_LENGTH, &val);
837    return val;
838}
839
840static napi_value DefineSendableClass(napi_env env) {
841    napi_value str;
842    napi_create_string_utf8(env, "str", NAPI_AUTO_LENGTH, &str);
843
844    napi_property_descriptor props[] = {
845        {"staticStr", nullptr, nullptr, nullptr, nullptr, str,
846         static_cast<napi_property_attributes>(napi_static | napi_writable), nullptr},
847        {"staticFunc", nullptr, func, nullptr, nullptr, nullptr, napi_static, nullptr},
848        {"str", nullptr, nullptr, nullptr, nullptr, str, static_cast<napi_property_attributes>(1 << 9 | napi_writable),
849         nullptr},
850        {"func", nullptr, nullptr, nullptr, nullptr, nullptr,
851         static_cast<napi_property_attributes>(1 << 11 | napi_writable), nullptr},
852    };
853
854    napi_value sendableClass = nullptr;
855    napi_define_sendable_class(
856        env, "SendableClass", NAPI_AUTO_LENGTH,
857        [](napi_env env, napi_callback_info info) -> napi_value {
858            napi_value thisVar = nullptr;
859            napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
860            napi_value str;
861            napi_create_string_utf8(env, "instance str", NAPI_AUTO_LENGTH, &str);
862            napi_property_descriptor props[] = {
863                {"str", nullptr, nullptr, nullptr, nullptr, str, napi_default, nullptr},
864                {"func", nullptr, func, nullptr, nullptr, nullptr, napi_default, nullptr},
865            };
866            napi_define_properties(env, thisVar, sizeof(props) / sizeof(props[0]), props);
867            return thisVar;
868        },
869        nullptr, sizeof(props) / sizeof(props[0]), props, nullptr, &sendableClass);
870
871    return sendableClass;
872}
873
874EXTERN_C_START
875static napi_value Init(napi_env env, napi_value exports)
876{
877    napi_property_descriptor desc[] = {};
878    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
879    napi_value cons = DefineSendableClass(env);
880    napi_set_named_property(env, exports, "SendableClass", cons);
881    return exports;
882}
883EXTERN_C_END
884
885static napi_module demoModule = {
886    .nm_version = 1,
887    .nm_flags = 0,
888    .nm_filename = nullptr,
889    .nm_register_func = Init,
890    .nm_modname = "entry",
891    .nm_priv = ((void*)0),
892    .reserved = { 0 },
893};
894
895extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
896{
897    napi_module_register(&demoModule);
898}
899```
900<!-- @[napi_define_sendable_class](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
901
902接口声明
903
904```ts
905// index.d.ts
906@Sendable
907export class SendableClass {
908  static staticStr: string;
909  static staticFunc(): string;
910  str: string;
911  func(): string;
912}
913```
914<!-- @[napi_define_sendable_class_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
915
916ArkTS侧示例代码
917
918```ts
919import hilog from '@ohos.hilog';
920import testNapi from 'libentry.so';
921
922let value = new testNapi.SendableClass();
923hilog.info(0x0000, 'testTag', 'Node-API napi_define_sendable_class: %{public}s', value.str);
924```
925<!-- @[ark_napi_define_sendable_class](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
926
927**napi_create_sendable_object_with_properties**
928
929使用给定的napi_property_descriptor创建一个sendable对象。
930
931cpp部分代码
932
933```cpp
934#include "napi/native_api.h"
935
936static napi_value GetSendableObject(napi_env env, napi_callback_info info) {
937    napi_value val_true;
938    napi_get_boolean(env, true, &val_true);
939    napi_property_descriptor desc1[] = {
940        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
941    };
942    napi_value obj;
943    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
944    return obj;
945}
946```
947<!-- @[napi_create_sendable_object_with_properties](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
948
949接口声明
950
951```ts
952// index.d.ts
953export const getSendableObject: () => { x: true };
954```
955<!-- @[napi_create_sendable_object_with_properties_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
956
957ArkTS侧示例代码
958
959```ts
960import hilog from '@ohos.hilog';
961import testNapi from 'libentry.so';
962
963let value = testNapi.getSendableObject();
964hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_object_with_properties: %{public}s', JSON.stringify(value));
965```
966<!-- @[ark_napi_create_sendable_object_with_properties](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
967
968**napi_create_sendable_array**
969
970创建一个sendable数组。
971
972cpp部分代码
973
974```cpp
975#include "napi/native_api.h"
976
977static napi_value GetSendableArray(napi_env env, napi_callback_info info) {
978    napi_value result = nullptr;
979    napi_create_sendable_array(env, &result);
980    return result;
981}
982```
983<!-- @[napi_create_sendable_array](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
984
985接口声明
986
987```ts
988// index.d.ts
989export const getSendableArray: () => [];
990```
991<!-- @[napi_create_sendable_array_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
992
993ArkTS侧示例代码
994
995```ts
996import hilog from '@ohos.hilog';
997import testNapi from 'libentry.so';
998
999let value = testNapi.getSendableArray();
1000hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_array: %{public}s', JSON.stringify(value));
1001```
1002<!-- @[ark_napi_create_sendable_array](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1003
1004**napi_create_sendable_array_with_length**
1005
1006创建一个指定长度的sendable数组。
1007
1008cpp部分代码
1009
1010```cpp
1011static napi_value GetSendableArrayWithLength(napi_env env, napi_callback_info info) {
1012    napi_value result = nullptr;
1013    napi_create_sendable_array_with_length(env, 1, &result);
1014    return result;
1015}
1016```
1017<!-- @[napi_create_sendable_array_with_length](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1018
1019接口声明
1020
1021```ts
1022// index.d.ts
1023export const getSendableArrayWithLength: () => [];
1024```
1025<!-- @[napi_create_sendable_array_with_length_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1026
1027ArkTS侧示例代码
1028
1029```ts
1030import hilog from '@ohos.hilog';
1031import testNapi from 'libentry.so';
1032
1033let value = testNapi.getSendableArrayWithLength();
1034hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_array_with_length: %{public}s', JSON.stringify(value.length));
1035```
1036<!-- @[ark_napi_create_sendable_array_with_length](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1037
1038**napi_create_sendable_arraybuffer**
1039
1040创建一个sendable ArrayBuffer。
1041
1042cpp部分代码
1043
1044```cpp
1045#include "napi/native_api.h"
1046#include "hilog/log.h"
1047
1048static napi_value GetSendableArrayBuffer(napi_env env, napi_callback_info info) {
1049    static size_t LENGTH = 1024;
1050    void *data;
1051    napi_value result = nullptr;
1052    napi_create_sendable_arraybuffer(env, LENGTH, &data, &result);
1053    bool isArrayBuffer = false;
1054    napi_is_arraybuffer(env, result, &isArrayBuffer);
1055    OH_LOG_INFO(LOG_APP, "isArrayBuffer: %{public}d", isArrayBuffer);
1056    return result;
1057}
1058```
1059<!-- @[napi_create_sendable_arraybuffer](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1060
1061接口声明
1062
1063```ts
1064// index.d.ts
1065export const getSendableArrayBuffer: () => void;
1066```
1067<!-- @[napi_create_sendable_arraybuffer_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1068
1069ArkTS侧示例代码
1070
1071```ts
1072import hilog from '@ohos.hilog';
1073import testNapi from 'libentry.so';
1074
1075testNapi.getSendableArrayBuffer();
1076```
1077<!-- @[ark_napi_create_sendable_arraybuffer](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1078
1079**napi_create_sendable_typedarray**
1080
1081创建一个sendable TypedArray。
1082
1083cpp部分代码
1084
1085```cpp
1086#include "napi/native_api.h"
1087#include "hilog/log.h"
1088
1089static napi_value GetSendableTypedArray(napi_env env, napi_callback_info info) {
1090    static size_t LENGTH = 1024;
1091    static size_t OFFSET = 0;
1092    void *data;
1093    napi_value arraybuffer = nullptr;
1094    napi_create_sendable_arraybuffer(env, LENGTH, &data, &arraybuffer);
1095
1096    napi_value result = nullptr;
1097    napi_create_sendable_typedarray(env, napi_uint8_array, LENGTH, arraybuffer, OFFSET, &result);
1098    bool isTypedArray = false;
1099    napi_is_typedarray(env, result, &isTypedArray);
1100    OH_LOG_INFO(LOG_APP, "isTypedArray: %{public}d", isTypedArray);
1101    return result;
1102}
1103```
1104<!-- @[napi_create_sendable_typed_array](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1105
1106接口声明
1107
1108```ts
1109// index.d.ts
1110export const getSendableTypedArray: () => void;
1111```
1112<!-- @[napi_create_sendable_typed_array_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1113
1114ArkTS侧示例代码
1115
1116```ts
1117import hilog from '@ohos.hilog';
1118import testNapi from 'libentry.so';
1119
1120testNapi.getSendableTypedArray();
1121```
1122<!-- @[ark_napi_create_sendable_typed_array](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1123
1124**napi_wrap_sendable**
1125
1126包裹一个native实例到ArkTS对象中。
1127
1128cpp部分代码
1129
1130```cpp
1131#include "napi/native_api.h"
1132
1133static napi_value WrapSendable(napi_env env, napi_callback_info info) {
1134    napi_value val_true;
1135    napi_get_boolean(env, true, &val_true);
1136    napi_property_descriptor desc1[] = {
1137        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
1138    };
1139    napi_value obj;
1140    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
1141
1142    const char* testStr = "test";
1143    napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
1144
1145    return nullptr;
1146}
1147```
1148<!-- @[napi_wrap_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1149
1150接口声明
1151
1152```ts
1153// index.d.ts
1154export const wrapSendable: () => void;
1155```
1156<!-- @[napi_wrap_sendable_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1157
1158ArkTS侧示例代码
1159
1160```ts
1161import hilog from '@ohos.hilog';
1162import testNapi from 'libentry.so';
1163
1164testNapi.wrapSendable();
1165```
1166<!-- @[ark_napi_wrap_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1167
1168**napi_wrap_sendable_with_size**
1169
1170包裹一个native实例到ArkTS对象中并指定大小。
1171
1172cpp部分代码
1173
1174```cpp
1175#include "napi/native_api.h"
1176
1177static napi_value WrapSendableWithSize(napi_env env, napi_callback_info info) {
1178    napi_value val_true;
1179    napi_get_boolean(env, true, &val_true);
1180    napi_property_descriptor desc1[] = {
1181        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
1182    };
1183    napi_value obj;
1184    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
1185
1186    const char* testStr = "test";
1187    napi_wrap_sendable_with_size(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr, 100);
1188
1189    return nullptr;
1190}
1191```
1192<!-- @[napi_wrap_sendable_with_size](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1193
1194接口声明
1195
1196```ts
1197// index.d.ts
1198export const wrapSendableWithSize: () => void;
1199```
1200<!-- @[napi_wrap_sendable_with_size_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1201
1202ArkTS侧示例代码
1203
1204```ts
1205import hilog from '@ohos.hilog';
1206import testNapi from 'libentry.so';
1207
1208testNapi.wrapSendableWithSize();
1209```
1210<!-- @[ark_napi_wrap_sendable_with_size](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1211
1212**napi_unwrap_sendable**
1213
1214获取ArkTS对象包裹的native实例。
1215
1216cpp部分代码
1217
1218```cpp
1219#include "napi/native_api.h"
1220
1221static napi_value UnwrapSendable(napi_env env, napi_callback_info info) {
1222    napi_value val_true;
1223    napi_get_boolean(env, true, &val_true);
1224    napi_property_descriptor desc1[] = {
1225        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
1226    };
1227    napi_value obj;
1228    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
1229
1230    const char* testStr = "test";
1231    napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
1232
1233    char* tmpTestStr = nullptr;
1234    napi_unwrap_sendable(env, obj, (void**)&tmpTestStr);
1235    OH_LOG_INFO(LOG_APP, "native value is %{public}s", tmpTestStr);
1236
1237    return nullptr;
1238}
1239```
1240<!-- @[napi_unwrap_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1241
1242接口声明
1243
1244```ts
1245// index.d.ts
1246export const unwrapSendable: () => void;
1247```
1248<!-- @[napi_unwrap_sendable_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1249
1250ArkTS侧示例代码
1251
1252```ts
1253import hilog from '@ohos.hilog';
1254import testNapi from 'libentry.so';
1255
1256testNapi.unwrapSendable();
1257```
1258<!-- @[ark_napi_unwrap_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1259
1260**napi_remove_wrap_sendable**
1261
1262移除并获取ArkTS对象包裹的native实例,移除后回调将不再触发,需手动delete释放内存。
1263
1264cpp部分代码
1265
1266```cpp
1267#include "napi/native_api.h"
1268
1269static napi_value RemoveWrapSendable(napi_env env, napi_callback_info info) {
1270    napi_value val_true;
1271    napi_get_boolean(env, true, &val_true);
1272    napi_property_descriptor desc1[] = {
1273        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
1274    };
1275    napi_value obj;
1276    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
1277
1278    const char* testStr = "test";
1279    napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
1280
1281    char* tmpTestStr = nullptr;
1282    napi_remove_wrap_sendable(env, obj, (void**)&tmpTestStr);
1283    OH_LOG_INFO(LOG_APP, "native value is %{public}s", tmpTestStr);
1284
1285    return nullptr;
1286}
1287```
1288<!-- @[napi_remove_wrap_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/napi_init.cpp) -->
1289
1290接口声明
1291
1292```ts
1293// index.d.ts
1294export const removeWrapSendable: () => void;
1295```
1296<!-- @[napi_remove_wrap_sendable_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/cpp/types/libentry/Index.d.ts) -->
1297
1298ArkTS侧示例代码
1299
1300```ts
1301import hilog from '@ohos.hilog';
1302import testNapi from 'libentry.so';
1303
1304testNapi.removeWrapSendable();
1305```
1306<!-- @[ark_napi_remove_wrap_sendable](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIExtendCapabilities/entry/src/main/ets/pages/Index.ets) -->
1307
1308以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
1309
1310```text
1311// CMakeLists.txt
1312add_definitions( "-DLOG_DOMAIN=0xd0d0" )
1313add_definitions( "-DLOG_TAG=\"testTag\"" )
1314target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so)
1315```
1316
1317
1318## napi_wrap接口增强
1319
1320### 接口描述
1321
1322| 接口 | 描述 |
1323| -------- | -------- |
1324| napi_wrap_enhance | 在ArkTS对象上绑定一个Node-API模块对象实例并指定实例大小,开发者可以指定绑定的回调函数是否异步执行,如果异步执行,则回调函数必须是线程安全的。 |
1325
1326### 使用示例
1327
1328**napi_wrap_enhance**
1329
1330在ArkTS对象上绑定一个Node-API模块对象实例并指定实例大小,开发者可以指定绑定的回调函数是否异步执行,如果异步执行,则回调函数必须是线程安全的。
1331
1332cpp部分代码
1333
1334```cpp
1335#include "napi/native_api.h"
1336
1337static napi_value TestNapiWrapEnhance(napi_env env, napi_callback_info info)
1338{
1339    napi_value testClass = nullptr;
1340    napi_define_class(
1341        env, "TestClass", NAPI_AUTO_LENGTH,
1342        [](napi_env env, napi_callback_info info) -> napi_value {
1343            napi_value thisVar = nullptr;
1344            napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1345            return thisVar;
1346        },
1347        nullptr, 0, nullptr, &testClass);
1348
1349    napi_value obj = nullptr;
1350    napi_new_instance(env, testClass, 0, nullptr, &obj);
1351    const char* testStr = "test";
1352    napi_ref wrappedRef = nullptr;
1353    napi_wrap_enhance(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, false, nullptr, sizeof(testStr), &wrappedRef);
1354    return nullptr;
1355}
1356```
1357
1358接口声明
1359
1360```ts
1361// index.d.ts
1362export const testNapiWrapEnhance: () => void;
1363```
1364
1365ArkTS侧示例代码
1366
1367```ts
1368import hilog from '@ohos.hilog';
1369import testNapi from 'libentry.so';
1370
1371testNapi.testNapiWrapEnhance();
1372```
1373
1374## napi提供多上下文环境能力
1375
1376### 接口描述
1377
1378| 接口 | 描述 |
1379| -------- | -------- |
1380| napi_create_ark_context | 创建基础运行时上下文环境。 |
1381| napi_switch_ark_context | 切换到指定的运行时上下文环境。 |
1382| napi_destroy_ark_context | 销毁基础运行时上下文环境。 |
1383### 使用示例
1384
1385**napi_create_ark_context、napi_switch_ark_context、napi_destroy_ark_context**
1386
1387[使用扩展的Node-API接口创建、切换和销毁上下文环境](use-napi-about-context.md)