1# 使用Node-API接口进行array相关开发 2 3## 简介 4 5使用Node-API接口进行array相关开发时,调用相关接口可以在Node-API模块中直接操作和处理ArkTS中的数组。 6 7## 基本概念 8 9使用Node-API接口进行数组(array)相关开发时,涉及的基本概念主要包括数组的创建、访问、修改、遍历以及与数组相关的操作。这些概念对于理解如何在Node-API模块中与ArkTS数组交互非常重要。以下是一些关键概念: 10 11- **数组的创建**:在Node-API模块中需要创建一个新的ArkTS数组,可以使用napi_create_array接口创建数组,将数组传递给ArkTS层。 12- **数组相关操作**:在Node-API模块中通过对应的接口获取ArkTS数组的长度、检索指定索引处的元素以及设置指定索引处的元素值,从而实现Node-API模块与ArkTS数组的交互。 13- **TypedArray**:ArkTS中的TypedArray是一种用来描述二进制数据的类数组数据视图,可以简单理解为一种指定元素类型的数组,TypedArray没有直接构造器,但是可以用它的子类构造器构造TypedArray类型的数据。TypedArray的子类有:Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Int32Array等。 14- **DataView**:DataView是ArkTS中的一种视图,是可以从ArrayBuffer对象中读写多种数值类型的底层接口。 15- **ArrayBuffer**:ArrayBuffer是固定长度的二进制数据缓冲区。 16 17## 场景和功能介绍 18 19使用Node-API接口进行数组相关开发时,可以处理各种涉及ArkTS数组的操作和交互场景。以下是几个具体的使用场景介绍: 20| 接口 | 描述 | 21| -------- | -------- | 22| napi_create_array | 用于在Node-API模块中向ArkTS层创建一个ArkTS数组对象。 | 23| napi_create_array_with_length | 用于在Node-API模块中向ArkTS层创建指定长度的ArkTS数组时。 | 24| napi_get_array_length | 用于在Node-API模块中获取ArkTS数组对象的长度。 | 25| napi_is_array | 用于在Node-API模块中判断一个napi_value值是否为数组。 | 26| napi_set_element | 用于在Node-API模块中对ArkTS数组对象的特定索引处设置一个值。 | 27| napi_get_element | 用于在Node-API模块中从ArkTS数组对象的特定索引处获取一个值。 | 28| napi_has_element | 用于在Node-API模块中判断ArkTS数组对象请求索引处是否包含元素。 | 29| napi_delete_element | 用于在Node-API模块中从ArkTS数组对象中删除请求索引对应的元素。 | 30| napi_create_typedarray | 用于在Node-API模块中创建指定类型的TypedArray,例如Uint8Array、Int32Array等,通常用于将Node-API模块中的数据转换为ArkTS中的TypedArray,以便进行高性能的数据处理操作。 | 31| napi_is_typedarray | 用于在Node-API模块中判断一个给定的napi_value是否为TypedArray对象。 | 32| napi_get_typedarray_info | 用于在Node-API模块中获得某个TypedArray的各种属性。 | 33| napi_create_dataview | 用于在Node-API模块中创建一个DataView对象,可以访问和操作二进制数据。 | 34| napi_is_dataview | 用于在Node-API模块中判断给定的napi_value是否为ArkTS中的DataView对象。 | 35| napi_get_dataview_info | 用于在Node-API模块中获得某个DataView的各种属性。 | 36 37## 使用示例 38 39Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。具体使用见示例。 40 41### napi_create_array 42 43用于在Node-API模块中创建一个ArkTS数组。 44 45cpp部分代码 46 47```cpp 48#include "napi/native_api.h" 49 50static constexpr int INT_NUM_5 = 5; // 数组长度 51 52static napi_value CreateArray(napi_env env, napi_callback_info info) 53{ 54 // 创建一个空数组 55 napi_value jsArray = nullptr; 56 napi_create_array(env, &jsArray); 57 // 将创建好的数组进行赋值 58 for (int i = 0; i < INT_NUM_5; i++) { 59 napi_value element; 60 napi_create_int32(env, i, &element); 61 napi_set_element(env, jsArray, i, element); 62 } 63 // 返回已创建好的数组 64 return jsArray; 65} 66``` 67 68接口声明 69 70```ts 71// index.d.ts 72export const createArray: () => number[]; 73``` 74 75ArkTS侧示例代码 76 77```ts 78import hilog from '@ohos.hilog' 79import testNapi from 'libentry.so' 80 81hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_array:%{public}s', JSON.stringify(testNapi.createArray())); 82``` 83 84### napi_create_array_with_length 85 86用于在Node-API模块中创建一个具有指定长度的ArkTS数组。 87 88cpp部分代码 89 90```cpp 91#include "napi/native_api.h" 92 93static napi_value CreateArrayWithLength(napi_env env, napi_callback_info info) 94{ 95 // 获取ArkTS侧传入的参数 96 size_t argc = 1; 97 napi_value argv[1] = {nullptr}; 98 napi_value jsArray = nullptr; 99 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 100 // 获取传递的数组长度 101 int32_t length = 0; 102 napi_get_value_int32(env, argv[0], &length); 103 // 使用napi_create_array_with_length创建指定长度的数组 104 napi_create_array_with_length(env, length, &jsArray); 105 // 返回数组 106 return jsArray; 107} 108``` 109 110接口声明 111 112```ts 113// index.d.ts 114export const createArrayWithLength: (length: number) => void[]; 115``` 116 117ArkTS侧示例代码 118 119```ts 120import hilog from '@ohos.hilog' 121import testNapi from 'libentry.so' 122 123let array = testNapi.createArrayWithLength(6); 124hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_array_with_length:%{public}d', array.length); 125``` 126 127### napi_get_array_length 128 129获取给定array的长度。 130 131cpp部分代码 132 133```cpp 134#include "napi/native_api.h" 135 136static napi_value GetArrayLength(napi_env env, napi_callback_info info) 137{ 138 // 获取ArkTS侧传入的参数 139 size_t argc = 1; 140 napi_value args[1] = {nullptr}; 141 napi_value result; 142 uint32_t length; 143 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 144 // 检查参数是否为数组 145 bool is_array; 146 napi_is_array(env, args[0], &is_array); 147 if (!is_array) { 148 napi_throw_type_error(env, nullptr, "Argument must be an array"); 149 return nullptr; 150 } 151 napi_get_array_length(env, args[0], &length); 152 // 创建返回值 153 napi_create_uint32(env, length, &result); 154 return result; 155} 156``` 157 158接口声明 159 160```ts 161// index.d.ts 162export const getArrayLength: (arr: Array<any>) => number | void; 163``` 164 165ArkTS侧示例代码 166 167```ts 168import hilog from '@ohos.hilog' 169import testNapi from 'libentry.so' 170 171const arr = [0, 1, 2, 3, 4, 5]; 172hilog.info(0x0000, 'testTag', 'Test Node-API get_array_length:%{public}d', testNapi.getArrayLength(arr)); 173``` 174 175### napi_is_array 176 177判断给定ArkTS值是否为数组。 178 179cpp部分代码 180 181```cpp 182#include "napi/native_api.h" 183 184static napi_value IsArray(napi_env env, napi_callback_info info) 185{ 186 // 获取ArkTS侧传入的参数 187 size_t argc = 1; 188 napi_value args[1] = {nullptr}; 189 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 190 // 调用napi_is_array接口判断给定入参是否为array数组 191 bool result; 192 napi_status status; 193 status = napi_is_array(env, args[0], &result); 194 if (status != napi_ok) { 195 napi_throw_error(env, nullptr, "Node-API napi_is_array fail"); 196 return nullptr; 197 } 198 // 将结果转成napi_value类型返回 199 napi_value returnValue; 200 napi_get_boolean(env, result, &returnValue); 201 202 return returnValue; 203} 204``` 205 206接口声明 207 208```ts 209// index.d.ts 210export const isArray: <T>(data: Array<T> | T) => boolean | void; 211``` 212 213ArkTS侧示例代码 214 215```ts 216import hilog from '@ohos.hilog' 217import testNapi from 'libentry.so' 218try { 219 let value = new Array<number>(1); 220 let data = "123"; 221 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_array: %{public}s', testNapi.isArray<number>(value)); 222 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_array: %{public}s', testNapi.isArray<string>(data)); 223} catch (error) { 224 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_array error: %{public}s', error.message); 225} 226``` 227 228### napi_set_element 229 230用于在ArkTS数组中设置指定索引位置的元素。 231对于以索引值为键的object,可以使用napi_set_element来设置属性值。 232 233cpp部分代码 234 235```cpp 236#include "napi/native_api.h" 237 238static constexpr int INT_ARG_2 = 2; // 入参索引 239 240static napi_value NapiSetElement(napi_env env, napi_callback_info info) 241{ 242 // 获取ArkTS侧传入的参数 243 size_t argc = 3; 244 napi_value args[3] = {nullptr}; 245 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 246 // 检查第一个参数是否为数组 247 bool isArr = false; 248 napi_is_array(env, args[0], &isArr); 249 if (!isArr) { 250 napi_throw_type_error(env, nullptr, "Argument should be an object of type array"); 251 return nullptr; 252 } 253 // 获取要设置的元素索引 254 double index = 0; 255 napi_get_value_double(env, args[1], &index); 256 // 将传入的值设置到数组指定索引位置 257 napi_set_element(env, args[0], static_cast<uint32_t>(index), args[INT_ARG_2]); 258 259 return nullptr; 260} 261``` 262 263接口声明 264 265```ts 266export const napiSetElement: <T>(arr: Array<T>, index: number, value: T) => void; 267``` 268 269ArkTS侧示例代码 270 271```ts 272import hilog from '@ohos.hilog' 273import testNapi from 'libentry.so' 274let arr = [10, 20, 30]; 275testNapi.napiSetElement<number | string>(arr, 1, 'newElement'); 276testNapi.napiSetElement<number | string>(arr, 2, 50); 277hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_element arr: %{public}s', arr.toString()); 278hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_element arr[3]: %{public}s', arr[3]); 279interface MyObject { 280 first: number; 281 second: number; 282} 283let obj: MyObject = { 284 first: 1, 285 second: 2 286}; 287testNapi.napiSetElement<number | string | Object>(arr, 4, obj); 288let objAsString = JSON.stringify(arr[4]); 289hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_element arr[4]: %{public}s', objAsString); 290``` 291 292### napi_get_element 293 294用于从ArkTS数组中获取请求索引位置的元素值。请求索引值应在数组的有效范围内,如果索引超出数组长度,函数会返回undefined。 295 296cpp部分代码 297 298```cpp 299#include "napi/native_api.h" 300 301static napi_value NapiGetElement(napi_env env, napi_callback_info info) 302{ 303 // 获取ArkTS侧传入的参数 304 size_t argc = 2; 305 napi_value args[2] = {nullptr}; 306 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 307 // 获取请求元素的索引值 308 uint32_t index; 309 napi_get_value_uint32(env, args[1], &index); 310 // 获取请求索引位置的元素值并存储在result中 311 napi_value result; 312 napi_get_element(env, args[0], index, &result); 313 314 return result; 315} 316``` 317 318接口声明 319 320```ts 321// index.d.ts 322export const napiGetElement: <T>(arr: Array<T>, index: number) => number | string | Object | boolean | undefined; 323``` 324 325ArkTS侧示例代码 326 327```ts 328import hilog from '@ohos.hilog' 329import testNapi from 'libentry.so' 330 331interface MyObject { 332 first: number; 333 second: number; 334} 335let obj: MyObject = { 336 first: 1, 337 second: 2 338}; 339let arr = [10, 'hello', null, obj]; 340hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[0]: %{public}d', testNapi.napiGetElement<number | string | null | Object>(arr, 0)); 341hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[1]: %{public}s', testNapi.napiGetElement<number | string | null | Object>(arr, 1)); 342hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[2]: %{public}s', testNapi.napiGetElement<number | string | null | Object>(arr, 2)); 343hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[3]: %{public}s', testNapi.napiGetElement<number | string | null | Object>(arr, 3)); 344hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[4]: %{public}s', JSON.stringify(testNapi.napiGetElement(arr, 4))); 345hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[null]: %{public}s', testNapi.napiGetElement<number | string | null | Object>(arr, 5)); 346``` 347 348### napi_has_element 349 350用于判断ArkTS数组是否具有指定索引的元素。如果索引超出了对象的有效范围,函数返回false,表示没有元素。 351 352cpp部分代码 353 354```cpp 355#include "napi/native_api.h" 356 357static napi_value NapiHasElement(napi_env env, napi_callback_info info) 358{ 359 // 获取ArkTS侧传入的参数 360 size_t argc = 2; 361 napi_value args[2] = {nullptr}; 362 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 363 // 获取要判断的元素的索引 364 uint32_t index; 365 napi_get_value_uint32(env, args[1], &index); 366 // 判断指定索引位置的元素是否存在 367 bool hasElement = true; 368 napi_has_element(env, args[0], index, &hasElement); 369 // 将bool结果转换为napi_value并返回 370 napi_value result; 371 napi_get_boolean(env, hasElement, &result); 372 return result; 373} 374``` 375 376接口声明 377 378```ts 379// index.d.ts 380export const napiHasElement: <T>(arr: Array<T>, index: number) => boolean; 381``` 382 383ArkTS侧示例代码 384 385```ts 386import hilog from '@ohos.hilog' 387import testNapi from 'libentry.so' 388 389let arr = [10, 'hello', null, 'world']; 390hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_element arr[0]: %{public}s', testNapi.napiHasElement<number | string | null>(arr, 0)); 391hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_element arr[7]: %{public}s', testNapi.napiHasElement<number | string | null>(arr, 7)); 392``` 393 394### napi_delete_element 395 396用于从ArkTS数组对象中删除请求索引的元素。 397 398cpp部分代码 399 400```cpp 401#include "napi/native_api.h" 402 403static napi_value NapiDeleteElement(napi_env env, napi_callback_info info) 404{ 405 // 获取ArkTS侧传入的参数 406 size_t argc = 2; 407 napi_value args[2] = {nullptr}; 408 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 409 // 获取要删除的元素的索引 410 uint32_t index; 411 napi_get_value_uint32(env, args[1], &index); 412 // 尝试删除请求索引位置的元素 413 bool deleted = true; 414 napi_delete_element(env, args[0], index, &deleted); 415 // 将bool结果转换为napi_value并返回 416 napi_value result; 417 napi_get_boolean(env, deleted, &result); 418 return result; 419} 420``` 421 422接口声明 423 424```ts 425// index.d.ts 426export const napiDeleteElement: <T>(arr: Array<T>, index: number) => boolean; 427``` 428 429ArkTS侧示例代码 430 431```ts 432// 需要同时导入前文示例代码中的napiHasElement、napiGetElement接口 433import hilog from '@ohos.hilog' 434import testNapi from 'libentry.so' 435 436let arr = [10, 'hello', null, 'world']; 437hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_element arr[0]: %{public}s', testNapi.napiHasElement<number | string | null>(arr, 0)); 438hilog.info(0x0000, 'testTag', 'Test Node-API napi_delete_element arr[0]: %{public}s', testNapi.napiDeleteElement<number | string | null>(arr, 0)); 439hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_element deleted arr[0]: %{public}s', testNapi.napiHasElement<number | string | null>(arr, 0)); 440hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[0]: %{public}d', testNapi.napiGetElement<number | string | null>(arr, 0)); 441``` 442 443### napi_create_typedarray 444 445用于在Node-API模块中通过现有的ArrayBuffer创建指定类型的ArkTS TypedArray。 446 447cpp部分代码 448 449```cpp 450#include "napi/native_api.h" 451 452static napi_value CreateTypedArray(napi_env env, napi_callback_info info) 453{ 454 // 获取ArkTS侧传入的参数 455 size_t argc = 1; 456 napi_value args[1] = {nullptr}; 457 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 458 int32_t typeNum = 0; 459 napi_get_value_int32(env, args[0], &typeNum); 460 napi_typedarray_type arrayType; 461 // 用于存储每个元素的大小 462 size_t elementSize = 0; 463 // 根据传递的类型值选择创建对应的类型数组 464 arrayType = static_cast<napi_typedarray_type>(typeNum); 465 switch (typeNum) { 466 case napi_int8_array: 467 case napi_uint8_array: 468 case napi_uint8_clamped_array: 469 elementSize = sizeof(int8_t); 470 break; 471 case napi_int16_array: 472 case napi_uint16_array: 473 elementSize = sizeof(int16_t); 474 break; 475 case napi_int32_array: 476 case napi_uint32_array: 477 elementSize = sizeof(int32_t); 478 break; 479 case napi_float32_array: 480 elementSize = sizeof(float); 481 break; 482 case napi_float64_array: 483 elementSize = sizeof(double); 484 break; 485 case napi_bigint64_array: 486 case napi_biguint64_array: 487 elementSize = sizeof(int64_t); 488 break; 489 default: 490 // 默认创建napi_int8_array类型 491 arrayType = napi_int8_array; 492 elementSize = sizeof(int8_t); 493 break; 494 } 495 size_t length = 3; 496 napi_value arrayBuffer = nullptr; 497 napi_value typedArray = nullptr; 498 void *data; 499 // 创建一个ArrayBuffer 500 napi_create_arraybuffer(env, length * elementSize, (void **)&data, &arrayBuffer); 501 // 根据给定类型创建TypedArray 502 napi_create_typedarray(env, arrayType, length, arrayBuffer, 0, &typedArray); 503 return typedArray; 504} 505``` 506 507接口声明 508 509```ts 510// index.d.ts 511export const enum TypedArrayTypes { 512 INT8_ARRAY = 0, 513 UINT8_ARRAY, 514 UINT8_CLAMPED_ARRAY, 515 INT16_ARRAY, 516 UINT16_ARRAY, 517 INT32_ARRAY, 518 UINT32_ARRAY, 519 FLOAT32_ARRAY, 520 FLOAT64_ARRAY, 521 BIGINT64_ARRAY, 522 BIGuINT64_ARRAY, 523} 524export const createTypedArray: <T>(type: TypedArrayTypes) => T; 525``` 526 527ArkTS侧示例代码 528 529```ts 530import hilog from '@ohos.hilog' 531import testNapi from 'libentry.so' 532 533// 传递要创建的类型值 534let typedArray = testNapi.createTypedArray<Int8Array>(testNapi.TypedArrayTypes["INT8_ARRAY"]); 535if (typedArray instanceof Int8Array) { 536 hilog.info(0x0000, 'testTag', ' Node-API napi_create_typedarray: Int8Array'); 537} 538let uint8Array = testNapi.createTypedArray<Uint8Array>(testNapi.TypedArrayTypes["UINT8_ARRAY"]); 539if (uint8Array instanceof Uint8Array) { 540 hilog.info(0x0000, 'testTag', ' Node-API napi_create_typedarray: Uint8Array'); 541} 542``` 543 544需要对use-napi-process.md中的模块初始化部分进行修改,具体见如下: 545 546```cpp 547#include <string> 548 549EXTERN_C_START 550static napi_value Init(napi_env env, napi_value exports) 551{ 552 // 定义的TypedArray类型供ArkTS侧使用,用于存放typedArrayTypes类型,使用示例见ArkTS侧的createTypedArray函数 553 napi_value typedArrayTypes; 554 napi_create_object(env, &typedArrayTypes); 555 napi_value typeIndex; 556 std::string typeKeys[] = { 557 "INT8_ARRAY", "UINT8_ARRAY", "UINT8_CLAMPED_ARRAY", "INT16_ARRAY", "UINT16_ARRAY", "INT32_ARRAY", 558 "UINT32_ARRAY", "FLOAT32_ARRAY", "FLOAT64_ARRAY", "BIGINT64_ARRAY", "BIGUINT64_ARRAY", 559 }; 560 for (int32_t i = 0; i < sizeof(typeKeys) / sizeof(typeKeys[0]); i++) { 561 napi_create_int32(env, i, &typeIndex); 562 napi_set_named_property(env, typedArrayTypes, typeKeys[i].c_str(), typeIndex); 563 } 564 napi_property_descriptor desc[] = { 565 {"createTypedArray", nullptr, CreateTypedArray, nullptr, nullptr, nullptr, napi_default, nullptr}, 566 {"TypedArrayTypes", nullptr, nullptr, nullptr, nullptr, typedArrayTypes, napi_default, nullptr} 567 }; 568 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 569 return exports; 570} 571EXTERN_C_END 572 573``` 574 575### napi_is_typedarray 576 577用于在Node-API模块中判断ArkTS侧给定的napi_value是否为TypedArray对象。 578 579cpp部分代码 580 581```cpp 582#include "napi/native_api.h" 583 584static napi_value IsTypedarray(napi_env env, napi_callback_info info) 585{ 586 // 获取ArkTS侧传入的参数 587 size_t argc = 1; 588 napi_value args[1] = {nullptr}; 589 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 590 // 调用napi_is_typedarray接口判断给定入参类型是否为TypedArray。 591 bool result = false; 592 napi_status status; 593 status = napi_is_typedarray(env, args[0], &result); 594 if (status != napi_ok) { 595 napi_throw_error(env, nullptr, "Node-API napi_is_typedarray fail"); 596 return nullptr; 597 } 598 // 将结果转成napi_value类型返回。 599 napi_value returnValue = nullptr; 600 napi_get_boolean(env, result, &returnValue); 601 602 return returnValue; 603} 604``` 605 606接口声明 607 608```ts 609// index.d.ts 610export const isTypedarray: (data: Object) => boolean | void; 611``` 612 613ArkTS侧示例代码 614 615```ts 616import hilog from '@ohos.hilog' 617import testNapi from 'libentry.so' 618try { 619 let value = new Uint8Array([1, 2, 3, 4]); 620 let data = "123"; 621 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_typedarray: %{public}s', testNapi.isTypedarray(value)); 622 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_typedarray: %{public}s', testNapi.isTypedarray(data)); 623} catch (error) { 624 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_typedarray error: %{public}s', error.message); 625} 626``` 627 628### napi_get_typedarray_info 629 630获取给定TypedArray的各种属性。 631 632cpp部分代码 633 634```cpp 635#include "napi/native_api.h" 636 637static napi_value GetTypedarrayInfo(napi_env env, napi_callback_info info) 638{ 639 // 获取ArkTS侧传入的参数,第一个参数为需要获得的信息的TypedArray类型数据,第二个参数为需要获得的信息类型的枚举值 640 size_t argc = 2; 641 napi_value args[2] = {nullptr}; 642 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 643 // 将第二个参数转为int32类型便于比较 644 int32_t infoTypeParam; 645 napi_get_value_int32(env, args[1], &infoTypeParam); 646 // 定义枚举类型与ArkTS侧枚举类型InfoType顺序含义一致 647 enum InfoType { INFO_TYPE = 1, INFO_LENGTH, INFO_ARRAY_BUFFER, INFO_BYTE_OFFSET }; 648 void *data; 649 napi_typedarray_type type; 650 size_t byteOffset, length; 651 napi_value arraybuffer; 652 // 调用接口napi_get_typedarray_info获得TypedArray类型数据的信息 653 napi_get_typedarray_info(env, args[0], &type, &length, &data, &arraybuffer, &byteOffset); 654 napi_value result; 655 // 根据属性名,返回TypedArray对应的属性值 656 switch (infoTypeParam) { 657 case INFO_TYPE: 658 // 如果传入的参数是int8类型的TypedArray数据,它的类型(type)为napi_int8_array 659 napi_value int8_type; 660 napi_get_boolean(env, type == napi_int8_array, &int8_type); 661 result = int8_type; 662 break; 663 case INFO_LENGTH: 664 // TypedArray中元素的字节长度 665 napi_value napiLength; 666 napi_create_int32(env, length, &napiLength); 667 result = napiLength; 668 break; 669 case INFO_BYTE_OFFSET: 670 // TypedArray数组的第一个元素所在的基础原生数组中的字节偏移量 671 napi_value napiByteOffset; 672 napi_create_int32(env, byteOffset, &napiByteOffset); 673 result = napiByteOffset; 674 break; 675 case INFO_ARRAY_BUFFER: 676 // TypedArray下的ArrayBuffer 677 result = arraybuffer; 678 break; 679 default: 680 break; 681 } 682 return result; 683} 684``` 685 686接口声明 687 688```ts 689// index.d.ts 690export const getTypedarrayInfo: <T>(typeArray: T, infoType: number) => ArrayBuffer | number | boolean; 691``` 692 693ArkTS侧示例代码 694 695```ts 696import hilog from '@ohos.hilog' 697import testNapi from 'libentry.so' 698 699// 传入TypedArray类型数据。TypedArray是一种用来描述二进制数据的类数组数据视图,没有直接构造器,可以用其子类构造类数组 700// TypedArray的子类有: Int8Array Uint8Array Uint8ClampedArray Int16Array Int32Array等 701let int8Array = new Int8Array([15, 7]); 702// 定义枚举类型 这些都是TypedArray的属性 703enum InfoType { 704 TYPE = 1, // 传入的TypedArray的类型 705 LENGTH = 2, // 传入的TypedArray的长度 706 ARRAY_BUFFER = 3, // TypedArray下的ArrayBuffer 707 BYTE_OFFSET = 4 // 数组的第一个元素所在的基础原生数组中的字节偏移量 708}; 709let arrbuff = testNapi.getTypedarrayInfo(int8Array, InfoType.ARRAY_BUFFER) as ArrayBuffer; 710// 将arraybuffer转为数组 711let arr = new Array(new Int8Array(arrbuff)); 712hilog.info(0x0000, 'Node-API', 'get_typedarray_info_arraybuffer: %{public}s', arr.toString()); 713hilog.info(0x0000, 'Node-API', 'get_typedarray_info_isIn8Array: %{public}s', testNapi.getTypedarrayInfo(int8Array, InfoType.TYPE).toString()); 714hilog.info(0x0000, 'Node-API', 'get_typedarray_info_length: %{public}d', testNapi.getTypedarrayInfo(int8Array, InfoType.LENGTH)); 715hilog.info(0x0000, 'Node-API', 'get_typedarray_info_byte_offset: %{public}d', testNapi.getTypedarrayInfo(int8Array, InfoType.BYTE_OFFSET)); 716``` 717 718### napi_create_dataview 719 720创建dataview对象,便于访问和操作二进制数据,需要提供一个指向二进制数据的缓冲区,并指定要包含的字节数。 721 722cpp部分代码 723 724```cpp 725#include "napi/native_api.h" 726 727static napi_value CreateDataView(napi_env env, napi_callback_info info) 728{ 729 // 获取ArkTS侧传入的参数 730 size_t argc = 1; 731 napi_value args[1] = {nullptr}; 732 napi_value arraybuffer = nullptr; 733 napi_value result = nullptr; 734 // DataView的字节长度 735 size_t byteLength = 12; 736 // 字节偏移量 737 size_t byteOffset = 4; 738 // 获取回调函数的参数信息 739 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 740 // 将参数转换为对象类型 741 napi_coerce_to_object(env, args[0], &arraybuffer); 742 // 创建一个数据视图对象,并指定字节长度和字节偏移量 743 napi_status status = napi_create_dataview(env, byteLength, arraybuffer, byteOffset, &result); 744 if (status != napi_ok) { 745 // 抛出创建DataView内容失败的错误 746 napi_throw_error(env, nullptr, "Failed to create DataView"); 747 return nullptr; 748 } 749 // 获取DataView的指针和长度信息 750 uint8_t *data = nullptr; 751 size_t length = 0; 752 napi_get_dataview_info(env, result, &length, (void **)&data, nullptr, nullptr); 753 // 为DataView赋值 754 for (size_t i = 0; i < length; i++) { 755 data[i] = static_cast<uint8_t>(i + 1); 756 } 757 return result; 758} 759``` 760 761接口声明 762 763```ts 764// index.d.ts 765export const createDataView: (arraybuffer:ArrayBuffer) => DataView | void; 766``` 767 768ArkTS侧示例代码 769 770```ts 771import hilog from '@ohos.hilog' 772import testNapi from 'libentry.so' 773 774const arrayBuffer = new ArrayBuffer(16); 775const dataView = testNapi.createDataView(arrayBuffer) as DataView; 776hilog.info(0x0000, 'testTag', 'Test Node-API dataView:%{public}d', dataView.byteLength); 777hilog.info(0x0000, 'testTag', 'Test Node-API dataView第一个数据:%{public}d', dataView.getInt8(0)); 778``` 779 780### napi_is_dataview 781 782用于在Node-API模块中判断ArkTS侧给定的napi_value是否为DataView。 783 784cpp部分代码 785 786```cpp 787#include "napi/native_api.h" 788 789static napi_value IsDataView(napi_env env, napi_callback_info info) 790{ 791 // 获取ArkTS侧传入的参数 792 size_t argc = 1; 793 napi_value args[1] = {nullptr}; 794 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 795 796 // 调用napi_is_dataview接口判断给定入参是否为DataView数据。 797 bool result; 798 napi_status status; 799 status = napi_is_dataview(env, args[0], &result); 800 if (status != napi_ok) { 801 napi_throw_error(env, nullptr, "Node-API napi_is_dataview fail"); 802 return nullptr; 803 } 804 // 将结果转成napi_value类型返回。 805 napi_value returnValue; 806 napi_get_boolean(env, result, &returnValue); 807 808 return returnValue; 809} 810``` 811 812接口声明 813 814```ts 815// index.d.ts 816export const isDataView: (date: DataView | string) => boolean | void; 817``` 818 819ArkTS侧示例代码 820 821```ts 822import hilog from '@ohos.hilog' 823import testNapi from 'libentry.so' 824try { 825 let buffer = new ArrayBuffer(16); 826 let dataView = new DataView(buffer); 827 let data = "123"; 828 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_dataview: %{public}s', testNapi.isDataView(dataView)); 829 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_dataview: %{public}s', testNapi.isDataView(data)); 830} catch (error) { 831 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_dataview error: %{public}s', error.message); 832} 833``` 834 835### napi_get_dataview_info 836 837获取给定DataView的各种属性。 838 839cpp部分代码 840 841```cpp 842#include "napi/native_api.h" 843 844static napi_value GetDataViewInfo(napi_env env, napi_callback_info info) 845{ 846 // 获取ArkTS侧传入的参数 847 size_t argc = 2; 848 napi_value args[2] = {nullptr}; 849 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 850 // 将第二个参数转为int32类型的数字 851 int32_t infoType; 852 napi_get_value_int32(env, args[1], &infoType); 853 size_t byteLength; 854 void *data; 855 napi_value arrayBuffer; 856 size_t byteOffset; 857 // 定义枚举类型与ArkTS侧枚举类型InfoType顺序含义一致 858 enum InfoType { BYTE_LENGTH = 0, ARRAY_BUFFER, BYTE_OFFSET }; 859 // 获取dataview信息 860 napi_get_dataview_info(env, args[0], &byteLength, &data, &arrayBuffer, &byteOffset); 861 napi_value result; 862 switch (infoType) { 863 case BYTE_LENGTH: 864 // 返回查询DataView的字节数 865 napi_value napiByteLength; 866 napi_create_int32(env, byteLength, &napiByteLength); 867 result = napiByteLength; 868 break; 869 case ARRAY_BUFFER: 870 // 返回查询DataView的arraybuffer 871 result = arrayBuffer; 872 break; 873 case BYTE_OFFSET: 874 // 返回查询DataView的偏移字节量 875 napi_value napiByteOffset; 876 napi_create_int32(env, byteOffset, &napiByteOffset); 877 result = napiByteOffset; 878 break; 879 default: 880 break; 881 } 882 return result; 883} 884``` 885 886接口声明 887 888```ts 889// index.d.ts 890export const getDataViewInfo: (dataView: DataView, infoType: number) => ArrayBuffer | number; 891``` 892 893ArkTS侧示例代码 894 895```ts 896import hilog from '@ohos.hilog' 897import testNapi from 'libentry.so' 898 899// 创建一个ArrayBuffer 900let arrayBuffer = new Int8Array([2, 5]).buffer; 901// 使用arrayBuffer创建一个dataView 902let dataView = new DataView(arrayBuffer); 903// 定义一个枚举类型 904enum InfoType { 905 BYTE_LENGTH = 0, 906 ARRAY_BUFFER = 1, 907 BYTE_OFFSET = 2, 908}; 909// 传入DataView类型参数查询DataView的字节数 910hilog.info(0x0000, 'Node-API', 'get_dataview_info_bytelength %{public}d', testNapi.getDataViewInfo(dataView, InfoType.BYTE_LENGTH)); 911// 传入DataView类型参数查询DataView的ArrayBuffer 912let arrbuff = testNapi.getDataViewInfo(dataView, InfoType.ARRAY_BUFFER) as ArrayBuffer; 913// 将arraybuffer转为数组 914let arr = Array.from(new Int8Array(arrbuff)); 915hilog.info(0x0000, 'Node-API', 'get_dataview_info_arraybuffer %{public}s', arr.toString()); 916// 传入DataView类型参数查询DataView开始投影的数据缓冲区中的字节偏移量 917hilog.info(0x0000, 'Node-API', 'get_dataview_info_byteoffset %{public}d', testNapi.getDataViewInfo(dataView, InfoType.BYTE_OFFSET)); 918``` 919 920以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"): 921 922```text 923// CMakeLists.txt 924add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 925add_definitions( "-DLOG_TAG=\"testTag\"" ) 926target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 927``` 928