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

#### 简介

使用JSVM-API接口进行object相关开发，处理JavaScript对象的基本操作，例如创建对象、获取原型、冻结和密封对象，检查对象的类型等。这些操作是在处理JavaScript对象时非常常见的，提供了一种与JavaScript对象交互的方式。

#### 基本概念

在JSVM接口开发中，经常需要定义和操作对象。例如，创建一个接口，该接口接受一个对象作为输入参数，对该对象执行某些操作，并返回一个结果对象。在这个过程中，需要确保接口的定义清晰、规范，并且与对象的属性和方法相兼容。

*   **接口（API）**：接口定义了组件之间的交互协议，包括输入参数、输出结果以及可能的错误处理。通过接口，组件可以相互调用和交换数据，而无需了解对方的内部实现细节。
*   **对象（Object）**：在JavaScript中，对象是一种复合数据类型，允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值，而方法则是对象可以执行的操作。

#### 接口说明

| 接口 | 功能说明 |
| :-- | :-- |
| OH\_JSVM\_GetPrototype | 获取给定JavaScript对象的原型。 |
| OH\_JSVM\_CreateObject | 创建一个默认的JavaScript Object对象。 |
| OH\_JSVM\_ObjectFreeze | 冻结给定的对象，防止向其添加新属性，删除现有属性，防止更改现有属性的可枚举性、可配置性或可写性，并防止更改现有属性的值。 |
| OH\_JSVM\_ObjectSeal | 密封给定的对象。这可以防止向其添加新属性，以及将所有现有属性标记为不可配置。 |
| OH\_JSVM\_Typeof | 返回JavaScript对象的类型。 |
| OH\_JSVM\_Instanceof | 判断一个对象是否是某个构造函数的实例。 |
| OH\_JSVM\_TypeTagObject | 将type\_tag指针的值与JavaScript对象或外部对象相关联。 |
| OH\_JSVM\_CheckObjectTypeTag | 检查给定的类型标签是否与对象上的类型标签匹配。 |
| OH\_JSVM\_CreateSymbol | 根据给定的描述符创建一个Symbol对象。 |
| OH\_JSVM\_SymbolFor | 在全局注册表中搜索具有给定描述的现有Symbol，如果该Symbol已经存在，它将被返回，否则将在注册表中创建一个新Symbol。 |
| OH\_JSVM\_CreateExternal | 创建一个包装了外部指针的JavaScript对象。 |
| OH\_JSVM\_GetValueExternal | 获取先前传递给OH\_JSVM\_CreateExternal的外部数据指针。 |

#### 使用示例

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

#### \[h2\]OH\_JSVM\_GetPrototype

该函数用于获取给定JavaScript对象的原型。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <fstream>
#include <string>
// GetPrototype注册回调
// OH\_JSVM\_GetPrototype的样例方法
static JSVM\_Value GetPrototype(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value argv\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    JSVM\_Value result{nullptr};
    JSVM\_Status status = OH\_JSVM\_GetPrototype(env, argv\[0\], &result);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetPrototype fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetPrototype success");
    }
    return result;
}
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetPrototype},
};
static JSVM\_CallbackStruct \*method = param;
// GetPrototype方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(const myObject = {};
    const proto = getPrototype(myObject);
    console.info(proto === Object.prototype);)JS";

预期的输出结果：

JSVM GetPrototype success

#### \[h2\]OH\_JSVM\_CreateObject

该函数创建一个默认的JavaScript Object对象。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <fstream>
// OH\_JSVM\_CreateObject的样例方法
static JSVM\_Value CreateObject(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    JSVM\_Value object = nullptr;
    // 创建一个空对象
    JSVM\_Status status = OH\_JSVM\_CreateObject(env, &object);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateObject fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateObject success");
    }
    // 设置对象的属性
    JSVM\_Value name = nullptr;
    // 设置属性名为 "name"
    OH\_JSVM\_CreateStringUtf8(env, "name", JSVM\_AUTO\_LENGTH, &name);
    JSVM\_Value value = nullptr;
    // 设置属性值为 "Hello from N-API!"
    OH\_JSVM\_CreateStringUtf8(env, "Hello OH\_JSVM\_CreateObject!", JSVM\_AUTO\_LENGTH, &value);
    // 将属性设置到对象上
    OH\_JSVM\_SetProperty(env, object, name, value);
    return object;
}
// CreateObject注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateObject},
};
static JSVM\_CallbackStruct \*method = param;
// CreateObject方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(createObject())JS";

预期的输出结果：

JSVM CreateObject success

#### \[h2\]OH\_JSVM\_ObjectFreeze

冻结给定的对象，防止向其添加新属性，移除现有属性，防止更改现有属性的可枚举性、可配置性或可写性，并防止更改现有属性的值。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_ObjectFreeze的样例方法
static JSVM\_Value ObjectFreeze(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 接受一个JavaScript侧传入的object
    size\_t argc = 1;
    JSVM\_Value argv\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    // 调用接口OH\_JSVM\_ObjectFreeze将传入的object冻结
    JSVM\_Status status = OH\_JSVM\_ObjectFreeze(env, argv\[0\]);
    if (status == JSVM\_OK) {
        OH\_LOG\_INFO(LOG\_APP, "Test JSVM OH\_JSVM\_ObjectFreeze success");
    }
    // 测试冻结后的对象中属性能否修改
    JSVM\_Value value = nullptr;
    OH\_JSVM\_CreateInt32(env, 111111, &value);
    OH\_JSVM\_SetNamedProperty(env, argv\[0\], "data", value);
    // 将冻结后修改过的属性返回JavaScript侧
    return argv\[0\];
}
// ObjectFreeze注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = ObjectFreeze},
};
static JSVM\_CallbackStruct \*method = param;
// ObjectFreeze方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(let obj = { data: 55, message: "hello world"};
  objectFreeze(obj))JS";

预期的输出结果：

Test JSVM OH\_JSVM\_ObjectFreeze success

#### \[h2\]OH\_JSVM\_ObjectSeal

密封给定的对象。这可以防止向该对象添加新属性，以及将所有现有属性标记为不可配置。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_ObjectSeal的样例方法
static JSVM\_Value ObjectSeal(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 接受一个JavaScript侧传入的object
    size\_t argc = 1;
    JSVM\_Value argv\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
    // 调用接口OH\_JSVM\_ObjectSeal将传入的object封闭，使其无法添加新的属性
    JSVM\_Status status = OH\_JSVM\_ObjectSeal(env, argv\[0\]);
    if (status == JSVM\_OK) {
        OH\_LOG\_INFO(LOG\_APP, "Test JSVM OH\_JSVM\_ObjectSeal success");
    }
    // 检查封闭后的对象中属性能否修改、删除、新增
    // 封闭后对象修改
    JSVM\_Value changeValue = nullptr;
    OH\_JSVM\_CreateInt32(env, 111111, &changeValue);
    OH\_JSVM\_SetNamedProperty(env, argv\[0\], "data", changeValue);
    // 封闭后对象删除
    JSVM\_Value deleteProperty = nullptr;
    OH\_JSVM\_CreateStringUtf8(env, "message", JSVM\_AUTO\_LENGTH, &deleteProperty);
    bool result = false;
    OH\_JSVM\_DeleteProperty(env, argv\[0\], deleteProperty, &result);
    if (result) {
        OH\_LOG\_INFO(LOG\_APP, "Test JSVM OH\_JSVM\_ObjectSeal failed");
    }
    // 封闭后对象新增
    JSVM\_Value addValue = nullptr;
    OH\_JSVM\_CreateStringUtf8(env, "addValue", JSVM\_AUTO\_LENGTH, &addValue);
    OH\_JSVM\_SetNamedProperty(env, argv\[0\], "newProperty", addValue);
    // 将封闭后改动过的对象返回JavaScript侧
    return argv\[0\];
}
// ObjectSeal注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = ObjectSeal},
};
static JSVM\_CallbackStruct \*method = param;
// ObjectSeal方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"objectSeal", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS( let obj = { data: 55, message: "hello world"};
  objectSeal(obj))JS";

预期的输出结果：

Test JSVM OH\_JSVM\_ObjectSeal success

#### \[h2\]OH\_JSVM\_Typeof

返回JavaScript对象的类型。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_Typeof的样例方法
static JSVM\_Value GetTypeof(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\_ValueType valueType;
    OH\_JSVM\_Typeof(env, args\[0\], &valueType);
    JSVM\_Value type = nullptr;
    switch (valueType) {
        case JSVM\_UNDEFINED:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is undefined");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is undefined", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_NULL:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is null");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is null", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_BOOLEAN:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is boolean");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is boolean", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_NUMBER:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is number");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is number", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_STRING:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is string");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is string", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_SYMBOL:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is symbol");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is symbol", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_OBJECT:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is object");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is object", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_FUNCTION:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is function");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is function", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_EXTERNAL:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is external");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is external", JSVM\_AUTO\_LENGTH, &type);
            break;
        case JSVM\_BIGINT:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type is bigint");
            OH\_JSVM\_CreateStringUtf8(env, "Input type is bigint", JSVM\_AUTO\_LENGTH, &type);
            break;
        default:
            OH\_LOG\_INFO(LOG\_APP, "JSVM Input type does not match any");
            OH\_JSVM\_CreateStringUtf8(env, " ", JSVM\_AUTO\_LENGTH, &type);
            break;
    }
    return type;
}
// GetTypeof注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetTypeof},
};
static JSVM\_CallbackStruct \*method = param;
// GetTypeof方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(getTypeof(true);)JS";

预期的输出结果：

JSVM Input type is boolean

#### \[h2\]OH\_JSVM\_Instanceof

判断一个对象是否是某个构造函数的实例。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_Instanceof的样例方法
static JSVM\_Value InstanceOf(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 获取两个JavaScript侧传入的参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    bool result = false;
    JSVM\_Status status = OH\_JSVM\_Instanceof(env, args\[0\], args\[1\], &result);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM InstanceOf fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM InstanceOf：%{public}d", result);
    }
    JSVM\_Value returnValue = nullptr;
    OH\_JSVM\_GetBoolean(env, result, &returnValue);
    return returnValue;
}
// InstanceOf注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = InstanceOf},
};
static JSVM\_CallbackStruct \*method = param;
// InstanceOf方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(class Person {
        name;
        age;
        constructor(name, age) {
          this.name = name;
          this.age = age;
        }
      }
     instanceOf(new Person('Alice', 30), Person);
     ;)JS";

预期的输出结果：

JSVM InstanceOf：1

#### \[h2\]OH\_JSVM\_TypeTagObject

使用类型标签type\_tag来标记JavaScript对象，这样在后续操作中可以更精确地识别JavaScript对象。

#### \[h2\]OH\_JSVM\_CheckObjectTypeTag

检查给定的类型标签是否与对象上的类型标签匹配。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#define NUMBERINT\_FOUR 4
// 定义一个静态常量JSVM\_TypeTag数组存储类型标签
static const JSVM\_TypeTag TagsData\[NUMBERINT\_FOUR\] = {
    {0x9e4b2449547061b3, 0x33999f8a6516c499},
    {0x1d55a794c53a726d, 0x43633f509f9c944e},
    {0, 0}, // 用于表示无标签或默认标签
    {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0},
};
// OH\_JSVM\_TypeTagObject的样例方法
static JSVM\_Value SetTypeTagToObject(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 获取两个JavaScript侧传入的参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 获取索引数字转换为JSVM\_Value
    int32\_t index = 0;
    OH\_JSVM\_GetValueInt32(env, args\[1\], &index);
    // 给参数（对象）设置类型标签
    JSVM\_Status status = OH\_JSVM\_TypeTagObject(env, args\[0\], &TagsData\[index\]);
    // 将bool结果转换为JSVM\_Value并返回
    JSVM\_Value result = nullptr;
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM SetTypeTagToObject fail");
        OH\_JSVM\_GetBoolean(env, false, &result);
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM SetTypeTagToObject success");
        OH\_JSVM\_GetBoolean(env, true, &result);
    }
    return result;
}
// OH\_JSVM\_CheckObjectTypeTag的样例方法
static JSVM\_Value CheckObjectTypeTag(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    // 获取两个JavaScript侧传入的参数
    size\_t argc = 2;
    JSVM\_Value args\[2\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    // 获取索引数字转换为JSVM\_Value
    int32\_t index = 0;
    OH\_JSVM\_GetValueInt32(env, args\[1\], &index);
    // 检查对象的类型标签
    bool checkResult = false;
    JSVM\_Status status = OH\_JSVM\_CheckObjectTypeTag(env, args\[0\], &TagsData\[index\], &checkResult);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CheckObjectTypeTag fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CheckObjectTypeTag:%{public}d", checkResult);
    }
    // 将bool结果转换为JSVM\_Value并返回
    JSVM\_Value checked = nullptr;
    OH\_JSVM\_GetBoolean(env, checkResult, &checked);
    return checked;
}
// SetTypeTagToObject，CheckObjectTypeTag注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = SetTypeTagToObject},
    {.data = nullptr, .callback = CheckObjectTypeTag},
};
static JSVM\_CallbackStruct \*method = param;
// SetTypeTagToObject，CheckObjectTypeTag方法别名，TS侧调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
    {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(
         class Obj {
           data;
           message;
         }
         let obj= { data: 0, message: "hello world"};
         setTypeTagToObject(obj, 0);
         checkObjectTypeTag(obj,0);)JS";

预期的输出结果：

JSVM SetTypeTagToObject success
JSVM CheckObjectTypeTag:1

#### \[h2\]OH\_JSVM\_CreateExternal

创建一个包装了外部指针的JavaScript对象。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d/v3/HxzBIFo7Th25mOgYDqHZKQ/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132820Z&HW-CC-Expire=86400&HW-CC-Sign=E3C738CC3E6A161DF8EF00C3D8021E0C3012A921EC294EB00C927797B567510A)

JavaScript对象被垃圾回收时，包装的外部指针指向的内容不被GC直接管理，仅调用传入的第三个参数对应的函数（如果传入时不为nullptr）。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <fstream>
// OH\_JSVM\_CreateExternal的样例方法
static JSVM\_Value CreateExternal(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t dataSize = 10;
    void \*data = malloc(dataSize);
    if (data == nullptr) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM Failed to malloc.");
        return nullptr;
    }
    memset(data, 0, dataSize);
    const char\* testStr = "test";
    JSVM\_Value external = nullptr;
    JSVM\_Status status = OH\_JSVM\_CreateExternal(
        env, data, \[\](JSVM\_Env env, void \*data, void \*hint) {free(data);}, (void \*)testStr, &external);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM Failed to create external data, status:%{public}d.", status);
        free(data);
        data = nullptr;
        return nullptr;
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateExternal success");
    }
    return external;
}
// CreateExternal注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateExternal},
};
static JSVM\_CallbackStruct \*method = param;
// CreateExternal方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(createExternal())JS";

预期的输出结果：

JSVM CreateExternal success

#### \[h2\]OH\_JSVM\_GetValueExternal

OH\_JSVM\_CreateExternal可以创建并包装自定义的C/C++对象，并将其公开给JavaScript代码，而OH\_JSVM\_GetValueExternal则用于获取OH\_JSVM\_CreateExternal所包装的外部对象的指针。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_GetValueExternal的样例方法
static JSVM\_Value GetValueExternal(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    static int data = 0x12345;
    JSVM\_Value externalValue = nullptr;
    JSVM\_Status status = OH\_JSVM\_CreateExternal(env, (void\*)&data, nullptr, nullptr, &externalValue);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM OH\_JSVM\_CreateExternal fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM OH\_JSVM\_CreateExternal success");
    }
    void \*data\_value;
    status = OH\_JSVM\_GetValueExternal(env, externalValue, &data\_value);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetValueExternal fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetValueExternal success");
    }
    // 将符号位转化为int类型传出去
    JSVM\_Value returnValue = nullptr;
    int retData = \*static\_cast<int \*>(data\_value);
    OH\_JSVM\_CreateInt32(env, retData, &returnValue);
    return returnValue;
}
// GetValueExternal注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetValueExternal},
};
static JSVM\_CallbackStruct \*method = param;
// GetValueExternal方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(getValueExternal())JS";

预期的输出结果：

JSVM OH\_JSVM\_CreateExternal success
JSVM GetValueExternal success

#### \[h2\]OH\_JSVM\_CreateSymbol

用于创建一个新的Symbol。Symbol是一种特殊的数据类型，用于表示唯一的标识符。与字符串或数字不同，符号的值是唯一的，即使两个符号具有相同的描述，它们也是不相等的。符号通常用作对象属性的键，以确保属性的唯一性。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// OH\_JSVM\_CreateSymbol的样例方法
static JSVM\_Value CreateSymbol(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    JSVM\_Value result = nullptr;
    const char \*des = "only";
    OH\_JSVM\_CreateStringUtf8(env, des, JSVM\_AUTO\_LENGTH, &result);
    JSVM\_Value returnSymbol = nullptr;
    OH\_JSVM\_CreateSymbol(env, result, &returnSymbol);
    JSVM\_ValueType valuetypeSymbol;
    OH\_JSVM\_Typeof(env, returnSymbol, &valuetypeSymbol);
    if (valuetypeSymbol == JSVM\_SYMBOL) {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateSymbol Success");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateSymbol fail");
    }
    return returnSymbol;
}
// CreateSymbol注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateSymbol},
};
static JSVM\_CallbackStruct \*method = param;
// CreateSymbol方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(createSymbol())JS";

预期的输出结果：

JSVM CreateSymbol Success

#### \[h2\]OH\_JSVM\_SymbolFor

在全局注册表中搜索具有给定描述的现有Symbol，如果该Symbol已经存在，它将被返回，否则将在注册表中创建一个新Symbol。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
// 定义一个常量，用于存储最大字符串长度
static const int MAX\_BUFFER\_SIZE = 128;
// OH\_JSVM\_SymbolFor的样例方法
static JSVM\_Value SymbolFor(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    JSVM\_Value description = nullptr;
    OH\_JSVM\_CreateStringUtf8(env, "test\_demo", 9, &description);
    char buffer\[MAX\_BUFFER\_SIZE\];
    size\_t bufferSize = MAX\_BUFFER\_SIZE;
    size\_t copied = 0;
    OH\_JSVM\_GetValueStringUtf8(env, description, buffer, bufferSize, &copied);
    JSVM\_Value symbol = nullptr;
    OH\_JSVM\_CreateSymbol(env, description, &symbol);
    JSVM\_Value result\_symbol = nullptr;
    JSVM\_Status status = OH\_JSVM\_SymbolFor(env, buffer, copied, &result\_symbol);
    JSVM\_ValueType valuetypeSymbol;
    OH\_JSVM\_Typeof(env, result\_symbol, &valuetypeSymbol);
    if (valuetypeSymbol == JSVM\_SYMBOL && status == JSVM\_OK) {
        OH\_LOG\_INFO(LOG\_APP, "JSVM OH\_JSVM\_SymbolFor success");
    }
    // 返回结果
    return result\_symbol;
}
// SymbolFor注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = SymbolFor},
};
static JSVM\_CallbackStruct \*method = param;
// SymbolFor方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};
// 样例测试js
const char\* srcCallNative = R"JS(symbolFor())JS";

预期的输出结果：

JSVM OH\_JSVM\_SymbolFor success