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 428import hilog from '@ohos.hilog' 429import testNapi from 'libentry.so' 430 431let arr = [10, 'hello', null, 'world']; 432hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_element arr[0]: %{public}s', testNapi.napiHasElement<number | string | null>(arr, 0)); 433hilog.info(0x0000, 'testTag', 'Test Node-API napi_delete_element arr[0]: %{public}s', testNapi.napiDeleteElement<number | string | null>(arr, 0)); 434hilog.info(0x0000, 'testTag', 'Test Node-API napi_has_element deleted arr[0]: %{public}s', testNapi.napiHasElement<number | string | null>(arr, 0)); 435hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_element arr[0]: %{public}d', testNapi.napiGetElement<number | string | null>(arr, 0)); 436``` 437 438### napi_create_typedarray 439 440用于在Node-API模块中通过现有的ArrayBuffer创建指定类型的ArkTS TypedArray。 441 442cpp部分代码 443 444```cpp 445#include "napi/native_api.h" 446 447static napi_value CreateTypedArray(napi_env env, napi_callback_info info) 448{ 449 // 获取ArkTS侧传入的参数 450 size_t argc = 1; 451 napi_value args[1] = {nullptr}; 452 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 453 int32_t typeNum = 0; 454 napi_get_value_int32(env, args[0], &typeNum); 455 napi_typedarray_type arrayType; 456 // 用于存储每个元素的大小 457 size_t elementSize = 0; 458 // 根据传递的类型值选择创建对应的类型数组 459 arrayType = static_cast<napi_typedarray_type>(typeNum); 460 switch (typeNum) { 461 case napi_int8_array: 462 case napi_uint8_array: 463 case napi_uint8_clamped_array: 464 elementSize = sizeof(int8_t); 465 break; 466 case napi_int16_array: 467 case napi_uint16_array: 468 elementSize = sizeof(int16_t); 469 break; 470 case napi_int32_array: 471 case napi_uint32_array: 472 elementSize = sizeof(int32_t); 473 break; 474 case napi_float32_array: 475 elementSize = sizeof(float); 476 break; 477 case napi_float64_array: 478 elementSize = sizeof(double); 479 break; 480 case napi_bigint64_array: 481 case napi_biguint64_array: 482 elementSize = sizeof(int64_t); 483 break; 484 default: 485 // 默认创建napi_int8_array类型 486 arrayType = napi_int8_array; 487 elementSize = sizeof(int8_t); 488 break; 489 } 490 size_t length = 3; 491 napi_value arrayBuffer = nullptr; 492 napi_value typedArray = nullptr; 493 void *data; 494 // 创建一个ArrayBuffer 495 napi_create_arraybuffer(env, length * elementSize, (void **)&data, &arrayBuffer); 496 // 根据给定类型创建TypedArray 497 napi_create_typedarray(env, arrayType, length, arrayBuffer, 0, &typedArray); 498 return typedArray; 499} 500``` 501 502接口声明 503 504```ts 505// index.d.ts 506export const enum TypedArrayTypes { 507 INT8_ARRAY = 0, 508 UINT8_ARRAY, 509 UINT8_CLAMPED_ARRAY, 510 INT16_ARRAY, 511 UINT16_ARRAY, 512 INT32_ARRAY, 513 UINT32_ARRAY, 514 FLOAT32_ARRAY, 515 FLOAT64_ARRAY, 516 BIGINT64_ARRAY, 517 BIGuINT64_ARRAY, 518} 519export const createTypedArray: <T>(type: TypedArrayTypes) => T; 520``` 521 522ArkTS侧示例代码 523 524```ts 525import hilog from '@ohos.hilog' 526import testNapi from 'libentry.so' 527 528// 传递要创建的类型值 529let typedArray = testNapi.createTypedArray<Int8Array>(testNapi.TypedArrayTypes["INT8_ARRAY"]); 530if (typedArray instanceof Int8Array) { 531 hilog.info(0x0000, 'testTag', ' Node-API napi_create_typedarray: Int8Array'); 532} 533let uint8Array = testNapi.createTypedArray<Uint8Array>(testNapi.TypedArrayTypes["UINT8_ARRAY"]); 534if (uint8Array instanceof Uint8Array) { 535 hilog.info(0x0000, 'testTag', ' Node-API napi_create_typedarray: Uint8Array'); 536} 537``` 538 539需要对use-napi-process.md中的模块初始化部分进行修改,具体见如下: 540 541```cpp 542#include <string> 543 544EXTERN_C_START 545static napi_value Init(napi_env env, napi_value exports) 546{ 547 // 定义的TypedArray类型供ArkTS侧使用,用于存放typedArrayTypes类型,使用示例见ArkTS侧的createTypedArray函数 548 napi_value typedArrayTypes; 549 napi_create_object(env, &typedArrayTypes); 550 napi_value typeIndex; 551 std::string typeKeys[] = { 552 "INT8_ARRAY", "UINT8_ARRAY", "UINT8_CLAMPED_ARRAY", "INT16_ARRAY", "UINT16_ARRAY", "INT32_ARRAY", 553 "UINT32_ARRAY", "FLOAT32_ARRAY", "FLOAT64_ARRAY", "BIGINT64_ARRAY", "BIGUINT64_ARRAY", 554 }; 555 for (int32_t i = 0; i < sizeof(typeKeys) / sizeof(typeKeys[0]); i++) { 556 napi_create_int32(env, i, &typeIndex); 557 napi_set_named_property(env, typedArrayTypes, typeKeys[i].c_str(), typeIndex); 558 } 559 napi_property_descriptor desc[] = { 560 {"createTypedArray", nullptr, CreateTypedArray, nullptr, nullptr, nullptr, napi_default, nullptr}, 561 {"TypedArrayTypes", nullptr, nullptr, nullptr, nullptr, typedArrayTypes, napi_default, nullptr} 562 }; 563 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 564 return exports; 565} 566EXTERN_C_END 567 568``` 569 570### napi_is_typedarray 571 572用于在Node-API模块中判断ArkTS侧给定的napi_value是否为TypedArray对象。 573 574cpp部分代码 575 576```cpp 577#include "napi/native_api.h" 578 579static napi_value IsTypedarray(napi_env env, napi_callback_info info) 580{ 581 // 获取ArkTS侧传入的参数 582 size_t argc = 1; 583 napi_value args[1] = {nullptr}; 584 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 585 // 调用napi_is_typedarray接口判断给定入参类型是否为TypedArray。 586 bool result = false; 587 napi_status status; 588 status = napi_is_typedarray(env, args[0], &result); 589 if (status != napi_ok) { 590 napi_throw_error(env, nullptr, "Node-API napi_is_typedarray fail"); 591 return nullptr; 592 } 593 // 将结果转成napi_value类型返回。 594 napi_value returnValue = nullptr; 595 napi_get_boolean(env, result, &returnValue); 596 597 return returnValue; 598} 599``` 600 601接口声明 602 603```ts 604// index.d.ts 605export const isTypedarray: <T>(data: T) => boolean | void; 606``` 607 608ArkTS侧示例代码 609 610```ts 611import hilog from '@ohos.hilog' 612import testNapi from 'libentry.so' 613try { 614 let value = new Uint8Array([1, 2, 3, 4]); 615 let data = "123"; 616 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_typedarray: %{public}s', testNapi.isTypedarray<number>(value)); 617 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_typedarray: %{public}s', testNapi.isTypedarray<string>(data)); 618} catch (error) { 619 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_typedarray error: %{public}s', error.message); 620} 621``` 622 623### napi_get_typedarray_info 624 625获取给定TypedArray的各种属性。 626 627cpp部分代码 628 629```cpp 630#include "napi/native_api.h" 631 632static napi_value GetTypedarrayInfo(napi_env env, napi_callback_info info) 633{ 634 // 获取ArkTS侧传入的参数,第一个参数为需要获得的信息的TypedArray类型数据,第二个参数为需要获得的信息类型的枚举值 635 size_t argc = 2; 636 napi_value args[2] = {nullptr}; 637 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 638 // 将第二个参数转为int32类型便于比较 639 int32_t infoTypeParam; 640 napi_get_value_int32(env, args[1], &infoTypeParam); 641 // 定义枚举类型与ArkTS侧枚举类型InfoType顺序含义一致 642 enum InfoType { INFO_TYPE = 1, INFO_LENGTH, INFO_ARRAY_BUFFER, INFO_BYTE_OFFSET }; 643 void *data; 644 napi_typedarray_type type; 645 size_t byteOffset, length; 646 napi_value arraybuffer; 647 // 调用接口napi_get_typedarray_info获得TypedArray类型数据的信息 648 napi_get_typedarray_info(env, args[0], &type, &length, &data, &arraybuffer, &byteOffset); 649 napi_value result; 650 // 根据属性名,返回TypedArray对应的属性值 651 switch (infoTypeParam) { 652 case INFO_TYPE: 653 // 如果传入的参数是int8类型的TypedArray数据,它的类型(type)为napi_int8_array 654 napi_value int8_type; 655 napi_get_boolean(env, type == napi_int8_array, &int8_type); 656 result = int8_type; 657 break; 658 case INFO_LENGTH: 659 // TypedArray中的元素数 660 napi_value napiLength; 661 napi_create_int32(env, length, &napiLength); 662 result = napiLength; 663 break; 664 case INFO_ARRAY_BUFFER: 665 // TypedArray数组的第一个元素所在的基础原生数组中的字节偏移量 666 napi_value napiByteOffset; 667 napi_create_int32(env, byteOffset, &napiByteOffset); 668 result = napiByteOffset; 669 break; 670 case INFO_BYTE_OFFSET: 671 // TypedArray下的ArrayBuffer 672 result = arraybuffer; 673 break; 674 default: 675 break; 676 } 677 return result; 678} 679``` 680 681接口声明 682 683```ts 684// index.d.ts 685export const getTypedarrayInfo: <T>(typeArray: T, infoType: number) => ArrayBuffer | number | boolean; 686``` 687 688ArkTS侧示例代码 689 690```ts 691import hilog from '@ohos.hilog' 692import testNapi from 'libentry.so' 693 694// 传入TypedArray类型数据。TypedArray是一种用来描述二进制数据的类数组数据视图,没有直接构造器,可以用其子类构造类数组 695// TypedArray的子类有: Int8Array Uint8Array Uint8ClampedArray Int16Array Int32Array等 696let int8Array = new Int8Array([15, 7]); 697// 定义枚举类型 这些都是TypedArray的属性 698enum InfoType { 699 TYPE = 1, // 传入的TypedArray的类型 700 LENGTH = 2, // 传入的TypedArray的长度 701 ARRAY_BUFFER = 3, // TypedArray下的ArrayBuffer 702 BYTE_OFFSET = 4 // 数组的第一个元素所在的基础原生数组中的字节偏移量 703}; 704let arrbuff = testNapi.getTypedarrayInfo(int8Array, InfoType.ARRAY_BUFFER) as ArrayBuffer; 705// 将arraybuffer转为数组 706let arr = Array.prototype.slice.call(new Int8Array(arrbuff)); 707hilog.info(0x0000, 'Node-API', 'get_typedarray_info_arraybuffer: %{public}s', arr.toString()); 708hilog.info(0x0000, 'Node-API', 'get_typedarray_info_isIn8Array: %{public}s', testNapi.getTypedarrayInfo(int8Array, InfoType.TYPE).toString()); 709hilog.info(0x0000, 'Node-API', 'get_typedarray_info_length: %{public}d', testNapi.getTypedarrayInfo(int8Array, InfoType.LENGTH)); 710hilog.info(0x0000, 'Node-API', 'get_typedarray_info_byte_offset: %{public}d', testNapi.getTypedarrayInfo(int8Array, InfoType.BYTE_OFFSET)); 711``` 712 713### napi_create_dataview 714 715创建dataview对象,便于访问和操作二进制数据,需要提供一个指向二进制数据的缓冲区,并指定要包含的字节数。 716 717cpp部分代码 718 719```cpp 720#include "napi/native_api.h" 721 722static napi_value CreateDataView(napi_env env, napi_callback_info info) 723{ 724 // 获取ArkTS侧传入的参数 725 size_t argc = 1; 726 napi_value args[1] = {nullptr}; 727 napi_value arraybuffer = nullptr; 728 napi_value result = nullptr; 729 // DataView的字节长度 730 size_t byteLength = 12; 731 // 字节偏移量 732 size_t byteOffset = 4; 733 // 获取回调函数的参数信息 734 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 735 // 将参数转换为对象类型 736 napi_coerce_to_object(env, args[0], &arraybuffer); 737 // 创建一个数据视图对象,并指定字节长度和字节偏移量 738 napi_status status = napi_create_dataview(env, byteLength, arraybuffer, byteOffset, &result); 739 if (status != napi_ok) { 740 // 抛出创建DataView内容失败的错误 741 napi_throw_error(env, nullptr, "Failed to create DataView"); 742 return nullptr; 743 } 744 // 获取DataView的指针和长度信息 745 uint8_t *data = nullptr; 746 size_t length = 0; 747 napi_get_dataview_info(env, result, &length, (void **)&data, nullptr, nullptr); 748 // 为DataView赋值 749 for (size_t i = 0; i < length; i++) { 750 data[i] = static_cast<uint8_t>(i + 1); 751 } 752 return result; 753} 754``` 755 756接口声明 757 758```ts 759// index.d.ts 760export const createDataView: (arraybuffer:ArrayBuffer) => DataView | void; 761``` 762 763ArkTS侧示例代码 764 765```ts 766import hilog from '@ohos.hilog' 767import testNapi from 'libentry.so' 768 769const arrayBuffer = new ArrayBuffer(16); 770const dataView = testNapi.createDataView(arrayBuffer) as DataView; 771hilog.info(0x0000, 'testTag', 'Test Node-API dataView:%{public}d', dataView.byteLength); 772hilog.info(0x0000, 'testTag', 'Test Node-API dataView第一个数据:%{public}d', dataView.getInt8(0)); 773``` 774 775### napi_is_dataview 776 777用于在Node-API模块中判断ArkTS侧给定的napi_value是否为DataView。 778 779cpp部分代码 780 781```cpp 782#include "napi/native_api.h" 783 784static napi_value IsDataView(napi_env env, napi_callback_info info) 785{ 786 // 获取ArkTS侧传入的参数 787 size_t argc = 1; 788 napi_value args[1] = {nullptr}; 789 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 790 791 // 调用napi_is_dataview接口判断给定入参是否为DataView数据。 792 bool result; 793 napi_status status; 794 status = napi_is_dataview(env, args[0], &result); 795 if (status != napi_ok) { 796 napi_throw_error(env, nullptr, "Node-API napi_is_dataview fail"); 797 return nullptr; 798 } 799 // 将结果转成napi_value类型返回。 800 napi_value returnValue; 801 napi_get_boolean(env, result, &returnValue); 802 803 return returnValue; 804} 805``` 806 807接口声明 808 809```ts 810// index.d.ts 811export const isDataView: (date: DataView | string) => boolean | void; 812``` 813 814ArkTS侧示例代码 815 816```ts 817import hilog from '@ohos.hilog' 818import testNapi from 'libentry.so' 819try { 820 let buffer = new ArrayBuffer(16); 821 let dataView = new DataView(buffer); 822 let data = "123"; 823 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_dataview: %{public}s', testNapi.isDataView(dataView)); 824 hilog.info(0x0000, 'testTag', 'Test Node-API napi_is_dataview: %{public}s', testNapi.isDataView(data)); 825} catch (error) { 826 hilog.error(0x0000, 'testTag', 'Test Node-API napi_is_dataview error: %{public}s', error.message); 827} 828``` 829 830### napi_get_dataview_info 831 832获取给定DataView的各种属性。 833 834cpp部分代码 835 836```cpp 837#include "napi/native_api.h" 838 839static napi_value GetDataViewInfo(napi_env env, napi_callback_info info) 840{ 841 // 获取ArkTS侧传入的参数 842 size_t argc = 2; 843 napi_value args[2] = {nullptr}; 844 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 845 // 将第二个参数转为int32类型的数字 846 int32_t infoType; 847 napi_get_value_int32(env, args[1], &infoType); 848 size_t byteLength; 849 void *data; 850 napi_value arrayBuffer; 851 size_t byteOffset; 852 // 定义枚举类型与ArkTS侧枚举类型InfoType顺序含义一致 853 enum InfoType { BYTE_LENGTH = 0, ARRAY_BUFFER, BYTE_OFFSET }; 854 // 获取dataview信息 855 napi_get_dataview_info(env, args[0], &byteLength, &data, &arrayBuffer, &byteOffset); 856 napi_value result; 857 switch (infoType) { 858 case BYTE_LENGTH: 859 // 返回查询DataView的字节数 860 napi_value napiByteLength; 861 napi_create_int32(env, byteLength, &napiByteLength); 862 result = napiByteLength; 863 break; 864 case ARRAY_BUFFER: 865 // 返回查询DataView的arraybuffer 866 result = arrayBuffer; 867 break; 868 case BYTE_OFFSET: 869 // 返回查询DataView的偏移字节量 870 napi_value napiByteOffset; 871 napi_create_int32(env, byteOffset, &napiByteOffset); 872 result = napiByteOffset; 873 break; 874 default: 875 break; 876 } 877 return result; 878} 879``` 880 881接口声明 882 883```ts 884// index.d.ts 885export const getDataViewInfo: (dataView: DataView, infoType: number) => ArrayBuffer | number; 886``` 887 888ArkTS侧示例代码 889 890```ts 891import hilog from '@ohos.hilog' 892import testNapi from 'libentry.so' 893 894// 创建一个ArrayBuffer 895let arrayBuffer = new Int8Array([2, 5]).buffer; 896// 使用arrayBuffer创建一个dataView 897let dataView = new DataView(arrayBuffer); 898// 定义一个枚举类型 899enum InfoType { 900 BYTE_LENGTH = 0, 901 ARRAY_BUFFER = 1, 902 BYTE_OFFSET = 2, 903}; 904// 传入DataView类型参数查询DataView的字节数 905hilog.info(0x0000, 'Node-API', 'get_dataview_info_bytelength %{public}d', testNapi.getDataViewInfo(dataView, InfoType.BYTE_LENGTH)); 906// 传入DataView类型参数查询DataView的ArrayBuffer 907let arrbuff = testNapi.getDataViewInfo(dataView, InfoType.ARRAY_BUFFER) as ArrayBuffer; 908// 将arraybuffer转为数组 909let arr = Array.from(new Int8Array(arrbuff)); 910hilog.info(0x0000, 'Node-API', 'get_dataview_info_arraybuffer %{public}s', arr.toString()); 911// 传入DataView类型参数查询DataView开始投影的数据缓冲区中的字节偏移量 912hilog.info(0x0000, 'Node-API', 'get_dataview_info_byteoffset %{public}d', testNapi.getDataViewInfo(dataView, InfoType.BYTE_OFFSET)); 913``` 914 915以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"): 916 917```text 918// CMakeLists.txt 919add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 920add_definitions( "-DLOG_TAG=\"testTag\"" ) 921target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 922``` 923