• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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