使用Node-API接口进行array相关开发
=======================

#### 简介

使用Node-API接口进行array相关开发时，调用相关接口可以在Node-API模块中直接操作和处理ArkTS中的数组。

#### 基本概念

使用Node-API接口进行数组（array）相关开发时，涉及的基本概念主要包括数组的创建、访问、修改、遍历以及与数组相关的操作。这些概念对于理解如何在Node-API模块中与ArkTS数组交互非常重要。以下是一些关键概念：

*   **数组的创建**：在Node-API模块中需要创建一个新的ArkTS数组。可以使用napi\_create\_array接口创建数组，并将数组传递给ArkTS层。
*   **数组相关操作**：在Node-API模块中通过对应的接口获取ArkTS数组的长度，检索指定索引处的元素以及设置指定索引处的元素值。这样可以实现Node-API模块与ArkTS数组的交互。
*   **TypedArray**：ArkTS 中的 TypedArray 是一种描述二进制数据的类数组数据视图，可以理解为指定元素类型的数组。TypedArray 没有直接构造器，但可以通过其子类构造器创建。TypedArray 的子类包括：Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Int32Array 等。
*   **DataView**：DataView是ArkTS中的一种灵活的二进制数据访问视图。它提供了从ArrayBuffer读取和写入多种数值类型的方法。与TypedArray不同，DataView不要求数据必须按特定字节对齐，因此可以处理任意字节偏移的数据结构。DataView支持以下方法（均有对应的get和set版本）：Int8、Uint8、Int16、Uint16、Int32、Uint32、Float32、Float64等。
*   **ArrayBuffer**：ArrayBuffer 是固定长度的二进制数据缓冲区。它不能直接读写，但可以通过 TypedArray 或 DataView 来操作其内容。

#### 场景和功能介绍

使用Node-API接口进行数组相关开发时，可以处理各种涉及ArkTS数组的操作和交互场景。以下是几个具体的使用场景介绍：

| 接口 | 描述 |
| :-- | :-- |
| [napi\_create\_array](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_create_array) | 用于在Node-API模块中向ArkTS层创建一个ArkTS数组对象。 |
| [napi\_create\_array\_with\_length](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_create_array_with_length) | 用于在Node-API模块中向ArkTS层创建指定长度的ArkTS数组对象。 |
| [napi\_get\_array\_length](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_get_array_length) | 用于在Node-API模块中获取ArkTS数组对象的长度。 |
| [napi\_is\_array](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_is_array) | 用于在Node-API模块中判断一个napi\_value值是否为数组。 |
| [napi\_set\_element](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_set_element) | 用于在Node-API模块中对ArkTS数组对象的特定索引处设置一个值。 |
| [napi\_get\_element](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_get_element) | 用于在Node-API模块中从ArkTS数组对象的特定索引处获取一个值。 |
| [napi\_has\_element](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_has_element) | 用于在Node-API模块中判断ArkTS数组对象请求索引处是否包含元素。 |
| [napi\_delete\_element](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_delete_element) | 用于在Node-API模块中从ArkTS数组对象中删除请求索引对应的元素。 |
| [napi\_create\_typedarray](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_create_typedarray) | 用于在Node-API模块中创建指定类型的TypedArray，例如Uint8Array、Int32Array等，通常用于将Node-API模块中的数据转换为ArkTS中的TypedArray，以便进行高性能的数据处理操作。 |
| [napi\_is\_typedarray](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_is_typedarray) | 用于在Node-API模块中判断一个给定的napi\_value是否为TypedArray对象。 |
| [napi\_get\_typedarray\_info](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_get_typedarray_info) | 用于在Node-API模块中获得某个TypedArray的各种属性。 |
| [napi\_create\_dataview](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_create_dataview) | 用于在Node-API模块中创建一个DataView对象，可以访问和操作二进制数据。 |
| [napi\_is\_dataview](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_is_dataview) | 用于在Node-API模块中判断给定的napi\_value是否为ArkTS中的DataView对象。 |
| [napi\_get\_dataview\_info](https://nodejs.org/docs/latest-v18.x/api/n-api.html#napi_get_dataview_info) | 用于在Node-API模块中获得某个DataView的各种属性。 |

#### 使用示例

Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-process)，本文仅对接口对应C++及ArkTS相关代码进行展示。具体使用见示例。

本文cpp部分代码所需引用的头文件如下：

#include "napi/native\_api.h"

本文ArkTS侧示例代码所需的模块导入如下：

import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

#### \[h2\]napi\_create\_array

用于在Node-API模块中创建一个ArkTS数组。

cpp部分代码

static constexpr int INT\_NUM\_5 = 5; // 入参索引 数组长度

// 使用Node-API接口进行array相关开发 napi\_create\_array
static napi\_value CreateArray(napi\_env env, napi\_callback\_info info)
{
    // 创建一个空数组
    napi\_value jsArray = nullptr;
    napi\_create\_array(env, &jsArray);
    // 将创建好的数组进行赋值
    for (int i = 0; i < INT\_NUM\_5; i++) {
        napi\_value element;
        napi\_create\_int32(env, i, &element);
        napi\_set\_element(env, jsArray, i, element);
    }
    // 返回已创建好的数组
    return jsArray;
}

接口声明

index.d.ts

export const createArray: () => number\[\]; // 使用Node-API接口进行array相关开发 napi\_create\_array

ArkTS侧示例代码

//使用Node-API接口进行array相关开发 napi\_create\_array
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_create\_array:%{public}s',
  JSON.stringify(testNapi.createArray()));

#### \[h2\]napi\_create\_array\_with\_length

用于在Node-API模块中创建一个具有指定长度的ArkTS数组。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_create\_array\_with\_length
static napi\_value CreateArrayWithLength(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value argv\[1\] = {nullptr};
    napi\_value jsArray = nullptr;
    napi\_get\_cb\_info(env, info, &argc, argv, nullptr, nullptr);
    // 获取传递的数组长度
    int32\_t length = 0;
    napi\_get\_value\_int32(env, argv\[0\], &length);
    // 使用napi\_create\_array\_with\_length创建指定长度的数组
    napi\_create\_array\_with\_length(env, length, &jsArray);
    // 返回数组
    return jsArray;
}

接口声明

index.d.ts

export const createArrayWithLength: (length: number) => void\[\]; // 使用Node-API接口进行array相关开发 napi\_create\_array\_with\_length

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_create\_array\_with\_length
let array = testNapi.createArrayWithLength(6);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_create\_array\_with\_length:%{public}d', array.length);

#### \[h2\]napi\_get\_array\_length

获取给定array的长度。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_get\_array\_length
static napi\_value GetArrayLength(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_value result;
    uint32\_t length;
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 检查参数是否为数组
    bool isArray;
    napi\_is\_array(env, args\[0\], &isArray);
    if (!isArray) {
        napi\_throw\_error(env, nullptr, "Argument must be an array");
        return nullptr;
    }
    napi\_get\_array\_length(env, args\[0\], &length);
    // 创建返回值
    napi\_create\_uint32(env, length, &result);
    return result;
}

接口声明

index.d.ts

export const getArrayLength: (arr: Array<any>) => number | undefined; // 使用Node-API接口进行array相关开发 napi\_get\_array\_length

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_get\_array\_length
const arr = \[0, 1, 2, 3, 4, 5\];
hilog.info(0x0000, 'testTag', 'Test Node-API get\_array\_length:%{public}d',
  testNapi.getArrayLength(arr));

#### \[h2\]napi\_is\_array

判断给定ArkTS值是否为数组。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_is\_array
static napi\_value IsArray(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 调用napi\_is\_array接口判断给定入参是否为array数组
    bool result = false;
    napi\_status status = napi\_is\_array(env, args\[0\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_is\_array fail");
        return nullptr;
    }
    // 将结果转成napi\_value类型返回
    napi\_value returnValue;
    napi\_get\_boolean(env, result, &returnValue);

    return returnValue;
}

接口声明

index.d.ts

export const isArray: <T>(data: Array<T> | T) => boolean | undefined; // 使用Node-API接口进行array相关开发 napi\_is\_array

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_is\_array
try {
  let value = new Array<number>(1);
  let data = "123";
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_is\_array: %{public}s',
    testNapi.isArray<number>(value));
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_is\_array: %{public}s',
    testNapi.isArray<string>(data));
  // ...
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_is\_array error: %{public}s', error.message);
  // ...
}

#### \[h2\]napi\_set\_element

用于在ArkTS数组中设置指定索引位置的元素。

对于以索引值为键的object，可以使用napi\_set\_element来设置属性值。

cpp部分代码

static constexpr int INT\_ARG\_2 = 2; // 入参索引
// ...
// 使用Node-API接口进行array相关开发 napi\_set\_element
static napi\_value NapiSetElement(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 3;
    napi\_value args\[3\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 检查第一个参数是否为数组
    bool isArr = false;
    napi\_is\_array(env, args\[0\], &isArr);
    if (!isArr) {
        napi\_throw\_error(env, nullptr, "Argument should be an object of type array");
        return nullptr;
    }
    // 获取要设置的元素索引
    double index = 0;
    napi\_status status = napi\_get\_value\_double(env, args\[1\], &index);
    if (status != napi\_ok || index < 0) {
        napi\_throw\_error(env, nullptr, "The index should be a non-negative number");
        return nullptr;
    }
    // 将传入的值设置到数组指定索引位置
    napi\_set\_element(env, args\[0\], static\_cast<uint32\_t>(index), args\[INT\_ARG\_2\]);

    return nullptr;
}

接口声明

index.d.ts

export const napiSetElement: <T>(arr: Array<T>, index: number,
  value: T) => void; // 使用Node-API接口进行array相关开发 napi\_set\_element

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_set\_element
try {
  let arr = \[10, 20, 30\];
  testNapi.napiSetElement<number | string>(arr, 1, 'newElement');
  testNapi.napiSetElement<number | string>(arr, 2, 50);
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_element arr: %{public}s', arr.toString());
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_element arr\[3\]: %{public}s', arr\[3\]);
  interface MyObject {
    first: number;
    second: number;
  }
  let obj: MyObject = {
    first: 1,
    second: 2
  };
  testNapi.napiSetElement<number | string | Object>(arr, 4, obj);
  let objAsString = JSON.stringify(arr\[4\]);
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_element arr\[4\]: %{public}s', objAsString);
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_set\_element error: %{public}s', error.message);
}

#### \[h2\]napi\_get\_element

用于从ArkTS数组中获取请求索引位置的元素值。请求索引值应在数组的有效范围内，如果索引超出数组长度，函数会返回undefined。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_get\_element
static napi\_value NapiGetElement(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 获取请求元素的索引值
    uint32\_t index;
    napi\_get\_value\_uint32(env, args\[1\], &index);
    // 获取请求索引位置的元素值并存储在result中
    napi\_value result;
    napi\_get\_element(env, args\[0\], index, &result);

    return result;
}

接口声明

index.d.ts

export const napiGetElement: <T>(arr: Array<T>,
  index: number) => number | string | Object | boolean | undefined; // 使用Node-API接口进行array相关开发 napi\_get\_element

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_get\_element
interface MyObject {
  first: number;
  second: number;
}

let obj: MyObject = {
  first: 1,
  second: 2
};
let arr = \[10, 'hello', null, obj\];
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[0\]: %{public}d',
  testNapi.napiGetElement<number | string | null | Object>(arr, 0));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[1\]: %{public}s',
  testNapi.napiGetElement<number | string | null | Object>(arr, 1));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[2\]: %{public}s',
  testNapi.napiGetElement<number | string | null | Object>(arr, 2));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[3\]: %{public}s',
  testNapi.napiGetElement<number | string | null | Object>(arr, 3));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[4\]: %{public}s',
  JSON.stringify(testNapi.napiGetElement(arr, 4)));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[null\]: %{public}s',
  testNapi.napiGetElement<number | string | null | Object>(arr, 5));

#### \[h2\]napi\_has\_element

用于判断ArkTS数组是否具有指定索引的元素。如果索引超出了对象的有效范围，函数返回false，表示没有元素。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_has\_element
static napi\_value NapiHasElement(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 获取要判断的元素的索引
    uint32\_t index;
    napi\_get\_value\_uint32(env, args\[1\], &index);
    // 判断指定索引位置的元素是否存在
    bool hasElement = true;
    napi\_has\_element(env, args\[0\], index, &hasElement);
    // 将bool结果转换为napi\_value并返回
    napi\_value result;
    napi\_get\_boolean(env, hasElement, &result);
    return result;
}

接口声明

index.d.ts

export const napiHasElement: <T>(arr: Array<T>, index: number) => boolean; // 使用Node-API接口进行array相关开发 napi\_has\_element

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_has\_element
let arr = \[10, 'hello', null, 'world'\];
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_element arr\[0\]: %{public}s',
  testNapi.napiHasElement<number | string | null>(arr, 0));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_element arr\[7\]: %{public}s',
  testNapi.napiHasElement<number | string | null>(arr, 7));

#### \[h2\]napi\_delete\_element

用于从ArkTS数组对象中删除请求索引的元素。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_delete\_element
static napi\_value NapiDeleteElement(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 获取要删除的元素的索引
    uint32\_t index;
    napi\_get\_value\_uint32(env, args\[1\], &index);
    // 尝试删除请求索引位置的元素
    bool deleted = true;
    napi\_delete\_element(env, args\[0\], index, &deleted);
    // 将bool结果转换为napi\_value并返回
    napi\_value result;
    napi\_get\_boolean(env, deleted, &result);
    return result;
}

接口声明

index.d.ts

export const napiDeleteElement: <T>(arr: Array<T>,
  index: number) => boolean; // 使用Node-API接口进行array相关开发 napi\_delete\_element

ArkTS侧示例代码

index.d.ts需要同时导入前文示例代码中的napiHasElement、napiGetElement接口。

// 使用Node-API接口进行array相关开发 napi\_delete\_element
let arr = \[10, 'hello', null, 'world'\];
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_element arr\[0\]: %{public}s',
  testNapi.napiHasElement<number | string | null>(arr, 0));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_delete\_element arr\[0\]: %{public}s',
  testNapi.napiDeleteElement<number | string | null>(arr, 0));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_has\_element deleted arr\[0\]: %{public}s',
  testNapi.napiHasElement<number | string | null>(arr, 0));
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_element arr\[0\]: %{public}d',
  testNapi.napiGetElement<number | string | null>(arr, 0));

#### \[h2\]napi\_create\_typedarray

用于在Node-API模块中通过现有的ArrayBuffer创建指定类型的ArkTS TypedArray。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_create\_typedarray
static napi\_value CreateTypedArray(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    int32\_t typeNum = 0;
    napi\_get\_value\_int32(env, args\[0\], &typeNum);
    napi\_typedarray\_type arrayType;
    // 用于存储每个元素的大小
    size\_t elementSize = 0;
    // 根据传递的类型值选择创建对应的类型数组
    arrayType = static\_cast<napi\_typedarray\_type>(typeNum);
    switch (arrayType) {
        case napi\_int8\_array:
        case napi\_uint8\_array:
        case napi\_uint8\_clamped\_array:
            elementSize = sizeof(int8\_t);
            break;
        case napi\_int16\_array:
        case napi\_uint16\_array:
            elementSize = sizeof(int16\_t);
            break;
        case napi\_int32\_array:
        case napi\_uint32\_array:
            elementSize = sizeof(int32\_t);
            break;
        case napi\_float32\_array:
            elementSize = sizeof(float);
            break;
        case napi\_float64\_array:
            elementSize = sizeof(double);
            break;
        case napi\_bigint64\_array:
        case napi\_biguint64\_array:
            elementSize = sizeof(int64\_t);
            break;
        default:
        // 默认创建napi\_int8\_array类型
            arrayType = napi\_int8\_array;
            elementSize = sizeof(int8\_t);
            break;
    }
    size\_t length = 3;
    napi\_value arrayBuffer = nullptr;
    napi\_value typedArray = nullptr;
    void \*data;
    // 创建一个ArrayBuffer
    napi\_create\_arraybuffer(env, length \* elementSize, (void \*\*)&data, &arrayBuffer);
    // 根据给定类型创建TypedArray
    napi\_create\_typedarray(env, arrayType, length, arrayBuffer, 0, &typedArray);
    return typedArray;
}

接口声明

index.d.ts

export const enum TypedArrayTypes {
  INT8\_ARRAY = 0,
  UINT8\_ARRAY,
  UINT8\_CLAMPED\_ARRAY,
  INT16\_ARRAY,
  UINT16\_ARRAY,
  INT32\_ARRAY,
  UINT32\_ARRAY,
  FLOAT32\_ARRAY,
  FLOAT64\_ARRAY,
  BIGINT64\_ARRAY,
  BIGUINT64\_ARRAY,
}

export const createTypedArray: <T>(type: TypedArrayTypes) => T; // 使用Node-API接口进行array相关开发 napi\_create\_typedarray

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_create\_typedarray
// 传递要创建的类型值
let typedArray = testNapi.createTypedArray<Int8Array>(testNapi.TypedArrayTypes\["INT8\_ARRAY"\]);
if (typedArray instanceof Int8Array) {
  hilog.info(0x0000, 'testTag', ' Node-API napi\_create\_typedarray: Int8Array');
  // ...
}
let uint8Array = testNapi.createTypedArray<Uint8Array>(testNapi.TypedArrayTypes\["UINT8\_ARRAY"\]);
if (uint8Array instanceof Uint8Array) {
  hilog.info(0x0000, 'testTag', ' Node-API napi\_create\_typedarray: Uint8Array');
  // ...
}

需要对use-napi-process.md中的模块初始化部分进行修改，具体见如下：

#include <string>

EXTERN\_C\_START
static napi\_value Init(napi\_env env, napi\_value exports)
{
    // 定义的TypedArray类型供ArkTS侧使用，用于存放typedArrayTypes类型，使用示例见ArkTS侧的createTypedArray函数
    napi\_value typedArrayTypes;
    napi\_create\_object(env, &typedArrayTypes);
    napi\_value typeIndex;
    std::string typeKeys\[\] = {
        "INT8\_ARRAY",   "UINT8\_ARRAY",   "UINT8\_CLAMPED\_ARRAY", "INT16\_ARRAY",      "UINT16\_ARRAY",    "INT32\_ARRAY",
        "UINT32\_ARRAY", "FLOAT32\_ARRAY", "FLOAT64\_ARRAY",       "BIGINT64\_ARRAY", "BIGUINT64\_ARRAY",
    };
    for (int32\_t i = 0; i < sizeof(typeKeys) / sizeof(typeKeys\[0\]); i++) {
        napi\_create\_int32(env, i, &typeIndex);
        napi\_set\_named\_property(env, typedArrayTypes, typeKeys\[i\].c\_str(), typeIndex);
    }
    napi\_property\_descriptor desc\[\] = {
        {"createTypedArray", nullptr, CreateTypedArray, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"TypedArrayTypes", nullptr, nullptr, nullptr, nullptr, typedArrayTypes, napi\_default, nullptr}
    };
    napi\_define\_properties(env, exports, sizeof(desc) / sizeof(desc\[0\]), desc);
    return exports;
}
EXTERN\_C\_END

#### \[h2\]napi\_is\_typedarray

用于在Node-API模块中判断ArkTS侧给定的napi\_value是否为TypedArray对象。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_is\_typedarray
static napi\_value IsTypedarray(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 调用napi\_is\_typedarray接口判断给定入参类型是否为TypedArray。
    bool result = false;
    napi\_status status = napi\_is\_typedarray(env, args\[0\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_is\_typedarray fail");
        return nullptr;
    }
    // 将结果转成napi\_value类型返回。
    napi\_value returnValue = nullptr;
    napi\_get\_boolean(env, result, &returnValue);

    return returnValue;
}

接口声明

index.d.ts

export const isTypedarray: (data: Object) => boolean | undefined; // 使用Node-API接口进行array相关开发 napi\_is\_typedarray

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_is\_typedarray
try {
  let value = new Uint8Array(\[1, 2, 3, 4\]);
  let data = "123";
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_is\_typedarray: %{public}s',
    testNapi.isTypedarray(value));
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_is\_typedarray: %{public}s',
    testNapi.isTypedarray(data));
  // ...
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_is\_typedarray error: %{public}s', error.message);
  // ...
}

#### \[h2\]napi\_get\_typedarray\_info

获取给定TypedArray的各种属性。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_get\_typedarray\_info
static napi\_value GetTypedarrayInfo(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数，第一个参数为需要获得的信息的TypedArray类型数据，第二个参数为需要获得的信息类型的枚举值
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 将第二个参数转为int32类型便于比较
    int32\_t infoTypeParam;
    napi\_get\_value\_int32(env, args\[1\], &infoTypeParam);
    // 定义枚举类型与ArkTS侧枚举类型InfoType顺序含义一致
    enum InfoType { INFO\_TYPE = 1, INFO\_LENGTH, INFO\_ARRAY\_BUFFER, INFO\_BYTE\_OFFSET };
    void \*data;
    napi\_typedarray\_type type;
    size\_t byteOffset;
    size\_t length;
    napi\_value arraybuffer;
    // 调用接口napi\_get\_typedarray\_info获得TypedArray类型数据的信息
    napi\_get\_typedarray\_info(env, args\[0\], &type, &length, &data, &arraybuffer, &byteOffset);
    napi\_value result = nullptr;
    // 根据属性名，返回TypedArray对应的属性值
    switch (infoTypeParam) {
        case INFO\_TYPE:
            // 如果传入的参数是int8类型的TypedArray数据，它的类型（type）为napi\_int8\_array
            napi\_value int8\_type;
            napi\_get\_boolean(env, type == napi\_int8\_array, &int8\_type);
            result = int8\_type;
            break;
        case INFO\_LENGTH:
            // TypedArray中元素的字节长度
            napi\_value napiLength;
            napi\_create\_int32(env, length, &napiLength);
            result = napiLength;
            break;
        case INFO\_BYTE\_OFFSET:
            // TypedArray数组的第一个元素所在的基础原生数组中的字节偏移量
            napi\_value napiByteOffset;
            napi\_create\_int32(env, byteOffset, &napiByteOffset);
            result = napiByteOffset;
            break;
        case INFO\_ARRAY\_BUFFER:
            // TypedArray下的ArrayBuffer
            result = arraybuffer;
            break;
        default:
            napi\_throw\_error(env, nullptr, "infoType is not the InfoType");
            break;
    }
    return result;
}

接口声明

index.d.ts

export const getTypedarrayInfo: <T>(typeArray: T,
  infoType: number) => ArrayBuffer | number | boolean; // 使用Node-API接口进行array相关开发 napi\_get\_typedarray\_info

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_get\_typedarray\_info
// 传入TypedArray类型数据。TypedArray是一种用来描述二进制数据的类数组数据视图，没有直接构造器，可以用其子类构造类数组
// TypedArray的子类有: Int8Array Uint8Array Uint8ClampedArray Int16Array Int32Array等
let int8Array = new Int8Array(\[15, 7\]);
// 定义枚举类型 这些都是TypedArray的属性
enum InfoType {
  TYPE = 1, // 传入的TypedArray的类型
  LENGTH = 2, // 传入的TypedArray的长度
  ARRAY\_BUFFER = 3, // TypedArray下的ArrayBuffer
  BYTE\_OFFSET = 4 // 数组的第一个元素所在的基础原生数组中的字节偏移量
};
try {
  let arrBuffer = testNapi.getTypedarrayInfo(int8Array, InfoType.ARRAY\_BUFFER) as ArrayBuffer;
  // 将arraybuffer转为数组
  let arr = new Array(new Int8Array(arrBuffer));
  hilog.info(0x0000, 'Node-API', 'get\_typedarray\_info\_arraybuffer: %{public}s', arr.toString());
  hilog.info(0x0000, 'Node-API', 'get\_typedarray\_info\_isIn8Array: %{public}s', testNapi.getTypedarrayInfo(int8Array, InfoType.TYPE).toString());
  hilog.info(0x0000, 'Node-API', 'get\_typedarray\_info\_length: %{public}d', testNapi.getTypedarrayInfo(int8Array, InfoType.LENGTH));
  hilog.info(0x0000, 'Node-API', 'get\_typedarray\_info\_byte\_offset: %{public}d', testNapi.getTypedarrayInfo(int8Array, InfoType.BYTE\_OFFSET));
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_get\_typedarray\_info error: %{public}s', error.message);
}

#### \[h2\]napi\_create\_dataview

创建dataview对象，便于访问和操作二进制数据，需要提供一个指向二进制数据的缓冲区，并指定要包含的字节数。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_create\_dataview
static napi\_value CreateDataView(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_value arraybuffer = nullptr;
    napi\_value result = nullptr;
    // DataView的字节长度
    size\_t byteLength = 12;
    // 字节偏移量
    size\_t byteOffset = 4;
    // 获取回调函数的参数信息
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 将参数转换为对象类型
    napi\_coerce\_to\_object(env, args\[0\], &arraybuffer);
    // 创建一个数据视图对象，并指定字节长度和字节偏移量
    napi\_status status = napi\_create\_dataview(env, byteLength, arraybuffer, byteOffset, &result);
    if (status != napi\_ok) {
        // 抛出创建DataView内容失败的错误
        napi\_throw\_error(env, nullptr, "Failed to create DataView");
        return nullptr;
    }
    // 获取DataView的指针和长度信息
    uint8\_t \*data = nullptr;
    size\_t length = 0;
    napi\_get\_dataview\_info(env, result, &length, (void \*\*)&data, nullptr, nullptr);
    // 为DataView赋值
    for (size\_t i = 0; i < length; i++) {
        data\[i\] = static\_cast<uint8\_t>(i + 1);
    }
    return result;
}

接口声明

index.d.ts

export const createDataView: (arraybuffer:ArrayBuffer) => DataView | undefined; // 使用Node-API接口进行array相关开发 napi\_create\_dataview

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_create\_dataview
const arrayBuffer = new ArrayBuffer(16);
const dataView = testNapi.createDataView(arrayBuffer) as DataView;
hilog.info(0x0000, 'testTag', 'Test Node-API dataView：%{public}d', dataView.byteLength);
hilog.info(0x0000, 'testTag', 'Test Node-API dataView第一个数据：%{public}d', dataView.getInt8(0));

#### \[h2\]napi\_is\_dataview

用于在Node-API模块中判断ArkTS侧给定的napi\_value是否为DataView。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_is\_dataview
static napi\_value IsDataView(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);

    // 调用napi\_is\_dataview接口判断给定入参是否为DataView数据。
    bool result = false;
    napi\_status status = napi\_is\_dataview(env, args\[0\], &result);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_is\_dataview fail");
        return nullptr;
    }
    // 将结果转成napi\_value类型返回。
    napi\_value returnValue;
    napi\_get\_boolean(env, result, &returnValue);

    return returnValue;
}

接口声明

index.d.ts

export const isDataView: (date: DataView | string) => boolean | undefined; // 使用Node-API接口进行array相关开发 napi\_is\_dataview

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_is\_dataview
try {
  let buffer = new ArrayBuffer(16);
  let dataView = new DataView(buffer);
  let data = "123";
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_is\_dataview: %{public}s',
    testNapi.isDataView(dataView));
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_is\_dataview: %{public}s',
    testNapi.isDataView(data));
  // ...
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_is\_dataview error: %{public}s', error.message);
  // ...
}

#### \[h2\]napi\_get\_dataview\_info

获取给定DataView的各种属性。

cpp部分代码

// 使用Node-API接口进行array相关开发 napi\_get\_dataview\_info
static napi\_value GetDataViewInfo(napi\_env env, napi\_callback\_info info)
{
    // 获取ArkTS侧传入的参数
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 将第二个参数转为int32类型的数字
    int32\_t infoType;
    napi\_get\_value\_int32(env, args\[1\], &infoType);
    size\_t byteLength;
    void \*data;
    napi\_value arrayBuffer;
    size\_t byteOffset;
    // 定义枚举类型与ArkTS侧枚举类型InfoType顺序含义一致
    enum InfoType { BYTE\_LENGTH = 0, ARRAY\_BUFFER, BYTE\_OFFSET };
    // 获取dataview信息
    napi\_get\_dataview\_info(env, args\[0\], &byteLength, &data, &arrayBuffer, &byteOffset);
    napi\_value result = nullptr;
    switch (infoType) {
        case BYTE\_LENGTH:
            // 返回查询DataView的字节数
            napi\_value napiByteLength;
            napi\_create\_int32(env, byteLength, &napiByteLength);
            result = napiByteLength;
            break;
        case ARRAY\_BUFFER:
            // 返回查询DataView的arraybuffer
            result = arrayBuffer;
            break;
        case BYTE\_OFFSET:
            // 返回查询DataView的偏移字节量
            napi\_value napiByteOffset;
            napi\_create\_int32(env, byteOffset, &napiByteOffset);
            result = napiByteOffset;
            break;
        default:
            napi\_throw\_error(env, nullptr, "infoType is not the InfoType");
            break;
    }
    return result;
}

接口声明

index.d.ts

export const getDataViewInfo: (dataView: DataView,
  infoType: number) => ArrayBuffer | number; // 使用Node-API接口进行array相关开发 napi\_get\_dataview\_info

ArkTS侧示例代码

// 使用Node-API接口进行array相关开发 napi\_get\_dataview\_info
// 创建一个ArrayBuffer
let arrayBuffer = new Int8Array(\[2, 5\]).buffer;
// 使用arrayBuffer创建一个dataView
let dataView = new DataView(arrayBuffer);
// 定义一个枚举类型
enum InfoType {
  BYTE\_LENGTH = 0,
  ARRAY\_BUFFER = 1,
  BYTE\_OFFSET = 2,
};
try {
  // 传入DataView类型参数查询DataView的字节数
  hilog.info(0x0000, 'Node-API', 'get\_dataview\_info\_bytelength %{public}d', testNapi.getDataViewInfo(dataView, InfoType.BYTE\_LENGTH));
  // 传入DataView类型参数查询DataView的ArrayBuffer
  let arrBuffer = testNapi.getDataViewInfo(dataView, InfoType.ARRAY\_BUFFER) as ArrayBuffer;
  // 将arraybuffer转为数组
  let arr = Array.from(new Int8Array(arrBuffer));
  hilog.info(0x0000, 'Node-API', 'get\_dataview\_info\_arraybuffer %{public}s', arr.toString());
  // 传入DataView类型参数查询DataView开始投影的数据缓冲区中的字节偏移量
  hilog.info(0x0000, 'Node-API', 'get\_dataview\_info\_byteoffset %{public}d', testNapi.getDataViewInfo(dataView, InfoType.BYTE\_OFFSET));
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_get\_dataview\_info error: %{public}s', error.message);
}

以上代码如果要在native cpp中打印日志，需在CMakeLists.txt文件中添加以下配置信息（并添加头文件：#include "hilog/log.h"）：

// CMakeLists.txt
add\_definitions( "-DLOG\_DOMAIN=0xd0d0" )
add\_definitions( "-DLOG\_TAG=\\"testTag\\"" )
target\_link\_libraries(entry PUBLIC libace\_napi.z.so libhilog\_ndk.z.so)