使用JSVM-API接口进行ArrayBuffer相关开发
=============================

#### 简介

ArrayBuffer 是 JavaScript 中的一种数据类型，用于表示通用的、固定长度的原始二进制数据缓冲区。它提供了一种在 JavaScript 中有效地表示和操作原始二进制数据的方式。

#### 基本概念

*   **ArrayBuffer**：ArrayBuffer 对象用来表示一个通用的、固定长度的原始二进制数据缓冲区。不能直接操作 ArrayBuffer 的内容，而是需要通过包装成 TypedArray 对象或 DataView 对象来读写。ArrayBuffer 常用于处理固定长度的原始二进制数据，如文件、网络数据包等。
*   **生命周期和内存管理**：在使用 JSVM 处理 ArrayBuffer 时，需要特别注意对象的生命周期管理，确保及时释放内存。

#### 接口说明

| 接口 | 功能说明 |
| :-- | :-- |
| OH\_JSVM\_GetArraybufferInfo | 检索 ArrayBuffer 的底层数据缓冲区及其长度。 |
| OH\_JSVM\_IsArraybuffer | 判断一个 JavaScript 对象是否为 ArrayBuffer 类型对象。 |
| OH\_JSVM\_DetachArraybuffer | 调用 ArrayBuffer 对象的 Detach 操作。 |
| OH\_JSVM\_IsDetachedArraybuffer | 检查给定的 ArrayBuffer 是否已被分离(Detached)。 |
| OH\_JSVM\_CreateArraybuffer | 创建一个指定大小的 ArrayBuffer 对象。 |

#### 使用示例

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

#### \[h2\]OH\_JSVM\_GetArraybufferInfo

检索 ArrayBuffer 的底层数据缓冲区及其长度。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_GetArraybufferInfo的示例方法
static JSVM\_Value GetArraybufferInfo(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    // 解析传递的参数
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 检查参数是否为ArrayBuffer
    bool isArrayBuffer = false;
    OH\_JSVM\_IsArraybuffer(env, args\[0\], &isArrayBuffer);
    if (!isArrayBuffer) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetArraybufferInfo isArrayBuffer:false");
        return nullptr;
    }
    void \*data;
    size\_t byteLength = 0;
    // 获取ArrayBuffer的底层数据缓冲区和长度
    JSVM\_Status status = OH\_JSVM\_GetArraybufferInfo(env, args\[0\], &data, &byteLength);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetArraybufferInfo: failed");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetArraybufferInfo: success");
    }
    return args\[0\];
}
// GetArraybufferInfo注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetArraybufferInfo},
};
static JSVM\_CallbackStruct \*method = param;
// GetArraybufferInfo方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getArraybufferInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 示例测试js
const char \*srcCallNative = R"JS(
getArraybufferInfo(new ArrayBuffer(10));
)JS";

预期结果：

JSVM GetArraybufferInfo: success

#### \[h2\]OH\_JSVM\_IsArraybuffer

判断一个 JavaScript 对象是否为 ArrayBuffer 类型对象。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_IsArraybuffer的示例方法
static JSVM\_Value IsArrayBuffer(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 调用OH\_JSVM\_IsArraybuffer接口判断给定入参是否为ArrayBuffer数据
    bool isArrayBuffer = false;
    JSVM\_Status status = OH\_JSVM\_IsArraybuffer(env, args\[0\], &isArrayBuffer);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM IsArrayBuffer: failed");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsArrayBuffer: success");
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsArrayBuffer: %{public}d", isArrayBuffer);
    }
    JSVM\_Value boolean = nullptr;
    OH\_JSVM\_GetBoolean(env, isArrayBuffer, &boolean);
    return boolean;
}
// IsArrayBuffer注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = IsArrayBuffer},
};
static JSVM\_CallbackStruct \*method = param;
// IsArrayBuffer方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"isArrayBuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 示例测试js
const char \*srcCallNative = R"JS(
isArrayBuffer(new ArrayBuffer(8));
)JS";

预期结果：

JSVM IsArrayBuffer: success
JSVM IsArrayBuffer: 1

#### \[h2\]OH\_JSVM\_DetachArraybuffer

调用 ArrayBuffer 对象的 Detach 操作。

#### \[h2\]OH\_JSVM\_IsDetachedArraybuffer

检查给定的 ArrayBuffer 是否已被分离。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_DetachArraybuffer、OH\_JSVM\_IsDetachedArraybuffer的示例方法
static JSVM\_Value DetachArraybuffer(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    JSVM\_Value arraybuffer = args\[0\];
    JSVM\_Status status = OH\_JSVM\_DetachArraybuffer(env, arraybuffer);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM DetachArraybuffer: failed");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM DetachArraybuffer: success");
    }
    return arraybuffer;
}
static JSVM\_Value IsDetachedArraybuffer(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    JSVM\_Value arraybuffer = args\[0\];
    OH\_JSVM\_DetachArraybuffer(env, arraybuffer);
    bool result = false;
    JSVM\_Status status = OH\_JSVM\_IsDetachedArraybuffer(env, arraybuffer, &result);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM IsDetachedArraybuffer: failed");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsDetachedArraybuffer: success");
        OH\_LOG\_INFO(LOG\_APP, "JSVM IsArrayBuffer: %{public}d", result);
    }
    JSVM\_Value isDetached = nullptr;
    OH\_JSVM\_GetBoolean(env, result, &isDetached);
    return isDetached;
}
// DetachArraybuffer、IsDetachedArraybuffer注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = DetachArraybuffer},
    {.data = nullptr, .callback = IsDetachedArraybuffer},
};
static JSVM\_CallbackStruct \*method = param;
// DetachArraybuffer、IsDetachedArraybuffer方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"detachArraybuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
    {"isDetachedArraybuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 示例测试js
const char \*srcCallNative = R"JS(
let arrayBuffer = new ArrayBuffer(10);
detachArraybuffer(arrayBuffer);
isDetachedArraybuffer(arrayBuffer);
)JS";

预期结果：

JSVM DetachArraybuffer: success
JSVM IsDetachedArraybuffer: success
JSVM IsArrayBuffer: 1

#### \[h2\]OH\_JSVM\_CreateArraybuffer

创建一个指定大小的 ArrayBuffer 对象。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_CreateArraybuffer的示例方法
static JSVM\_Value CreateArraybuffer(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value argv\[1\] = {nullptr};
    JSVM\_Value result = nullptr;
    // 解析传递的参数
    OH\_JSVM\_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    int32\_t value = 0;
    size\_t length = 0;
    JSVM\_CALL(OH\_JSVM\_GetValueInt32(env, argv\[0\], &value));
    length = size\_t(value);
    void \*data;
    // 创建一个新的ArrayBuffer
    JSVM\_Status status = OH\_JSVM\_CreateArraybuffer(env, length, &data, &result);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateArraybuffer: failed");
        return nullptr;
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateArraybuffer: success");
        OH\_LOG\_INFO(LOG\_APP, "JSVM ArrayBuffer length: %{public}d", length);
    }
    // 返回创建好的ArrayBuffer
    return result;
}
// CreateArraybuffer注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateArraybuffer},
};
static JSVM\_CallbackStruct \*method = param;
// CreateArraybuffer方法别名，供TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createArraybuffer", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 示例测试js
const char \*srcCallNative = R"JS(
createArraybuffer(8);
)JS";

预期结果：

JSVM CreateArraybuffer: success
JSVM ArrayBuffer length: 8