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 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)