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