• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用JSVM-API接口进行object相关开发
2<!--Kit: NDK Development-->
3<!--Subsystem: arkcompiler-->
4<!--Owner: @yuanxiaogou; @string_sz-->
5<!--Designer: @knightaoko-->
6<!--Tester: @test_lzz-->
7<!--Adviser: @fang-jinxu-->
8
9## 简介
10
11使用JSVM-API接口进行object相关开发,处理JavaScript对象的基本操作,例如创建对象、获取原型、冻结和密封对象,检查对象的类型等。这些操作是在处理JavaScript对象时非常常见的,提供了一种与JavaScript对象交互的方式。
12
13## 基本概念
14
15在JSVM接口开发中,经常需要定义和操作对象。例如,创建一个接口,该接口接受一个对象作为输入参数,对该对象执行某些操作,并返回一个结果对象。在这个过程中,需要确保接口的定义清晰、规范,并且与对象的属性和方法相兼容。
16
17- **接口(API)**:接口定义了组件之间的交互协议,包括输入参数、输出结果以及可能的错误处理。通过接口,组件可以相互调用和交换数据,而无需了解对方的内部实现细节。
18- **对象(Object)**:在JavaScript,对象是一种复合数据类型,允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值,而方法则是对象可以执行的操作。
19
20## 接口说明
21
22| 接口                       | 功能说明                                     |
23| -------------------------- | -------------------------------------------- |
24| OH_JSVM_GetPrototype         | 获取给定JavaScript对象的原型。             |
25| OH_JSVM_CreateObject         | 创建一个默认的JavaScript Object对象。                   |
26| OH_JSVM_ObjectFreeze         | 冻结给定的对象,防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。                             |
27| OH_JSVM_ObjectSeal           |  密封给定的对象。这可以防止向其添加新属性,以及将所有现有属性标记为不可配置。                             |
28| OH_JSVM_Typeof                | 返回JavaScript对象的类型。 |
29| OH_JSVM_Instanceof            | 判断一个对象是否是某个构造函数的实例。 |
30| OH_JSVM_TypeTagObject       | 将type_tag指针的值与JavaScript对象或外部对象相关联。 |
31| OH_JSVM_CheckObjectTypeTag | 检查给定的类型标签是否与对象上的类型标签匹配。 |
32| OH_JSVM_CreateSymbol         | 根据给定的描述符创建一个Symbol对象。                     |
33|OH_JSVM_SymbolFor | 在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新Symbol。 |
34| OH_JSVM_CreateExternal       | 创建一个包装了外部指针的JavaScript对象。               |
35| OH_JSVM_GetValueExternal    | 获取先前传递给OH_JSVM_CreateExternal的外部数据指针。                  |
36
37## 使用示例
38
39JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
40
41### OH_JSVM_GetPrototype
42
43该函数用于获取给定JavaScript对象的原型。
44
45cpp部分代码:
46
47```cpp
48// hello.cpp
49#include "napi/native_api.h"
50#include "ark_runtime/jsvm.h"
51#include <hilog/log.h>
52#include <fstream>
53#include <string>
54// GetPrototype注册回调
55// OH_JSVM_GetPrototype的样例方法
56static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info)
57{
58    size_t argc = 1;
59    JSVM_Value argv[1] = {nullptr};
60    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
61    JSVM_Value result{nullptr};
62    JSVM_Status status = OH_JSVM_GetPrototype(env, argv[0], &result);
63    if (status != JSVM_OK) {
64        OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail");
65    } else {
66        OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success");
67    }
68    return result;
69}
70static JSVM_CallbackStruct param[] = {
71    {.data = nullptr, .callback = GetPrototype},
72};
73static JSVM_CallbackStruct *method = param;
74// GetPrototype方法别名,供JS调用
75static JSVM_PropertyDescriptor descriptor[] = {
76    {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
77};
78// 样例测试js
79const char* srcCallNative = R"JS(const myObject = {};
80    const proto = getPrototype(myObject);
81    console.log(proto === Object.prototype);)JS";
82```
83<!-- @[oh_jsvm_get_prototype](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/getprototype/src/main/cpp/hello.cpp) -->
84
85预期的输出结果:
86```ts
87JSVM GetPrototype success
88```
89
90### OH_JSVM_CreateObject
91
92该函数创建一个默认的JavaScript Object对象。
93
94cpp部分代码:
95
96```cpp
97// hello.cpp
98#include "napi/native_api.h"
99#include "ark_runtime/jsvm.h"
100#include <hilog/log.h>
101#include <fstream>
102// OH_JSVM_CreateObject的样例方法
103static JSVM_Value CreateObject(JSVM_Env env, JSVM_CallbackInfo info)
104{
105    JSVM_Value object = nullptr;
106    // 创建一个空对象
107    JSVM_Status status = OH_JSVM_CreateObject(env, &object);
108    if (status != JSVM_OK) {
109        OH_LOG_ERROR(LOG_APP, "JSVM CreateObject fail");
110    } else {
111        OH_LOG_INFO(LOG_APP, "JSVM CreateObject success");
112    }
113    // 设置对象的属性
114    JSVM_Value name = nullptr;
115    // 设置属性名为 "name"
116    OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &name);
117    JSVM_Value value = nullptr;
118    // 设置属性值为 "Hello from N-API!"
119    OH_JSVM_CreateStringUtf8(env, "Hello OH_JSVM_CreateObject!", JSVM_AUTO_LENGTH, &value);
120    // 将属性设置到对象上
121    OH_JSVM_SetProperty(env, object, name, value);
122    return object;
123}
124// CreateObject注册回调
125static JSVM_CallbackStruct param[] = {
126    {.data = nullptr, .callback = CreateObject},
127};
128static JSVM_CallbackStruct *method = param;
129// CreateObject方法别名,供JS调用
130static JSVM_PropertyDescriptor descriptor[] = {
131    {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
132};
133// 样例测试js
134const char* srcCallNative = R"JS(createObject())JS";
135```
136<!-- @[oh_jsvm_create_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/createobject/src/main/cpp/hello.cpp) -->
137
138预期的输出结果:
139```ts
140JSVM CreateObject success
141```
142
143### OH_JSVM_ObjectFreeze
144
145冻结给定的对象,防止向其添加新属性,移除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。
146
147cpp部分代码:
148
149```cpp
150// hello.cpp
151#include "napi/native_api.h"
152#include "ark_runtime/jsvm.h"
153#include <hilog/log.h>
154// OH_JSVM_ObjectFreeze的样例方法
155static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info)
156{
157    // 接受一个JavaScript侧传入的object
158    size_t argc = 1;
159    JSVM_Value argv[1] = {nullptr};
160    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
161    // 调用接口OH_JSVM_ObjectFreeze将传入的object冻结
162    JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]);
163    if (status == JSVM_OK) {
164        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success");
165    }
166    // 测试冻结后的对象中属性能否修改
167    JSVM_Value value = nullptr;
168    OH_JSVM_CreateInt32(env, 111111, &value);
169    OH_JSVM_SetNamedProperty(env, argv[0], "data", value);
170    // 将冻结后修改过的属性返回JavaScript侧
171    return argv[0];
172}
173// ObjectFreeze注册回调
174static JSVM_CallbackStruct param[] = {
175    {.data = nullptr, .callback = ObjectFreeze},
176};
177static JSVM_CallbackStruct *method = param;
178// ObjectFreeze方法别名,供JS调用
179static JSVM_PropertyDescriptor descriptor[] = {
180    {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
181};
182// 样例测试js
183const char* srcCallNative = R"JS(let obj = { data: 55, message: "hello world"};
184  objectFreeze(obj))JS";
185```
186<!-- @[oh_jsvm_object_freeze](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/objectfreeze/src/main/cpp/hello.cpp) -->
187
188预期的输出结果:
189```ts
190Test JSVM OH_JSVM_ObjectFreeze success
191```
192
193### OH_JSVM_ObjectSeal
194
195密封给定的对象。这可以防止向该对象添加新属性,以及将所有现有属性标记为不可配置。
196
197cpp部分代码:
198
199```cpp
200// hello.cpp
201#include "napi/native_api.h"
202#include "ark_runtime/jsvm.h"
203#include <hilog/log.h>
204// OH_JSVM_ObjectSeal的样例方法
205static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info)
206{
207    // 接受一个JavaScript侧传入的object
208    size_t argc = 1;
209    JSVM_Value argv[1] = {nullptr};
210    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
211    // 调用接口OH_JSVM_ObjectSeal将传入的object封闭,使其无法添加新的属性
212    JSVM_Status status = OH_JSVM_ObjectSeal(env, argv[0]);
213    if (status == JSVM_OK) {
214        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal success");
215    }
216    // 检查封闭后的对象中属性能否修改、删除、新增
217    // 封闭后对象修改
218    JSVM_Value changeValue = nullptr;
219    OH_JSVM_CreateInt32(env, 111111, &changeValue);
220    OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue);
221    // 封闭后对象删除
222    JSVM_Value deleteProperty = nullptr;
223    OH_JSVM_CreateStringUtf8(env, "message", JSVM_AUTO_LENGTH, &deleteProperty);
224    bool result = false;
225    OH_JSVM_DeleteProperty(env, argv[0], deleteProperty, &result);
226    if (result) {
227        OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed");
228    }
229    // 封闭后对象新增
230    JSVM_Value addValue = nullptr;
231    OH_JSVM_CreateStringUtf8(env, "addValue", JSVM_AUTO_LENGTH, &addValue);
232    OH_JSVM_SetNamedProperty(env, argv[0], "newProperty", addValue);
233    // 将封闭后改动过的对象返回JavaScript侧
234    return argv[0];
235}
236// ObjectSeal注册回调
237static JSVM_CallbackStruct param[] = {
238    {.data = nullptr, .callback = ObjectSeal},
239};
240static JSVM_CallbackStruct *method = param;
241// ObjectSeal方法别名,供JS调用
242static JSVM_PropertyDescriptor descriptor[] = {
243    {"objectSeal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
244};
245// 样例测试js
246const char* srcCallNative = R"JS( let obj = { data: 55, message: "hello world"};
247  objectSeal(obj))JS";
248```
249<!-- @[oh_jsvm_object_seal](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/objectseal/src/main/cpp/hello.cpp) -->
250
251预期的输出结果:
252```ts
253Test JSVM OH_JSVM_ObjectSeal success
254```
255
256### OH_JSVM_Typeof
257
258返回JavaScript对象的类型。
259
260cpp部分代码:
261
262```cpp
263// hello.cpp
264#include "napi/native_api.h"
265#include "ark_runtime/jsvm.h"
266#include <hilog/log.h>
267// OH_JSVM_Typeof的样例方法
268static JSVM_Value GetTypeof(JSVM_Env env, JSVM_CallbackInfo info)
269{
270    size_t argc = 1;
271    JSVM_Value args[1] = {nullptr};
272    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
273    JSVM_ValueType valueType;
274    OH_JSVM_Typeof(env, args[0], &valueType);
275    JSVM_Value type = nullptr;
276    switch (valueType) {
277        case JSVM_UNDEFINED:
278            OH_LOG_INFO(LOG_APP, "JSVM Input type is undefined");
279            OH_JSVM_CreateStringUtf8(env, "Input type is undefined", JSVM_AUTO_LENGTH, &type);
280            break;
281        case JSVM_NULL:
282            OH_LOG_INFO(LOG_APP, "JSVM Input type is null");
283            OH_JSVM_CreateStringUtf8(env, "Input type is null", JSVM_AUTO_LENGTH, &type);
284            break;
285        case JSVM_BOOLEAN:
286            OH_LOG_INFO(LOG_APP, "JSVM Input type is boolean");
287            OH_JSVM_CreateStringUtf8(env, "Input type is boolean", JSVM_AUTO_LENGTH, &type);
288            break;
289        case JSVM_NUMBER:
290            OH_LOG_INFO(LOG_APP, "JSVM Input type is number");
291            OH_JSVM_CreateStringUtf8(env, "Input type is number", JSVM_AUTO_LENGTH, &type);
292            break;
293        case JSVM_STRING:
294            OH_LOG_INFO(LOG_APP, "JSVM Input type is string");
295            OH_JSVM_CreateStringUtf8(env, "Input type is string", JSVM_AUTO_LENGTH, &type);
296            break;
297        case JSVM_SYMBOL:
298            OH_LOG_INFO(LOG_APP, "JSVM Input type is symbol");
299            OH_JSVM_CreateStringUtf8(env, "Input type is symbol", JSVM_AUTO_LENGTH, &type);
300            break;
301        case JSVM_OBJECT:
302            OH_LOG_INFO(LOG_APP, "JSVM Input type is object");
303            OH_JSVM_CreateStringUtf8(env, "Input type is object", JSVM_AUTO_LENGTH, &type);
304            break;
305        case JSVM_FUNCTION:
306            OH_LOG_INFO(LOG_APP, "JSVM Input type is function");
307            OH_JSVM_CreateStringUtf8(env, "Input type is function", JSVM_AUTO_LENGTH, &type);
308            break;
309        case JSVM_EXTERNAL:
310            OH_LOG_INFO(LOG_APP, "JSVM Input type is external");
311            OH_JSVM_CreateStringUtf8(env, "Input type is external", JSVM_AUTO_LENGTH, &type);
312            break;
313        case JSVM_BIGINT:
314            OH_LOG_INFO(LOG_APP, "JSVM Input type is bigint");
315            OH_JSVM_CreateStringUtf8(env, "Input type is bigint", JSVM_AUTO_LENGTH, &type);
316            break;
317        default:
318            OH_LOG_INFO(LOG_APP, "JSVM Input type does not match any");
319            OH_JSVM_CreateStringUtf8(env, " ", JSVM_AUTO_LENGTH, &type);
320            break;
321    }
322    return type;
323}
324// GetTypeof注册回调
325static JSVM_CallbackStruct param[] = {
326    {.data = nullptr, .callback = GetTypeof},
327};
328static JSVM_CallbackStruct *method = param;
329// GetTypeof方法别名,TS侧调用
330static JSVM_PropertyDescriptor descriptor[] = {
331    {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
332};
333// 样例测试js
334const char* srcCallNative = R"JS(getTypeof(true);)JS";
335```
336<!-- @[oh_jsvm_typeof](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/typeof/src/main/cpp/hello.cpp) -->
337
338预期的输出结果:
339```ts
340JSVM Input type is boolean
341```
342
343### OH_JSVM_Instanceof
344
345判断一个对象是否是某个构造函数的实例。
346
347cpp部分代码:
348
349```cpp
350// hello.cpp
351#include "napi/native_api.h"
352#include "ark_runtime/jsvm.h"
353#include <hilog/log.h>
354// OH_JSVM_Instanceof的样例方法
355static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info)
356{
357    // 获取两个JavaScript侧传入的参数
358    size_t argc = 2;
359    JSVM_Value args[2] = {nullptr};
360    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
361    bool result = false;
362    JSVM_Status status = OH_JSVM_Instanceof(env, args[0], args[1], &result);
363    if (status != JSVM_OK) {
364        OH_LOG_ERROR(LOG_APP, "JSVM InstanceOf fail");
365    } else {
366        OH_LOG_INFO(LOG_APP, "JSVM InstanceOf:%{public}d", result);
367    }
368    JSVM_Value returnValue = nullptr;
369    OH_JSVM_GetBoolean(env, result, &returnValue);
370    return returnValue;
371}
372// InstanceOf注册回调
373static JSVM_CallbackStruct param[] = {
374    {.data = nullptr, .callback = InstanceOf},
375};
376static JSVM_CallbackStruct *method = param;
377// InstanceOf方法别名,TS侧调用
378static JSVM_PropertyDescriptor descriptor[] = {
379    {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
380};
381// 样例测试js
382const char* srcCallNative = R"JS(class Person {
383        name;
384        age;
385        constructor(name, age) {
386          this.name = name;
387          this.age = age;
388        }
389      }
390     instanceOf(new Person('Alice', 30), Person);
391     ;)JS";
392```
393<!-- @[oh_jsvm_instanceof](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/instanceof/src/main/cpp/hello.cpp) -->
394
395预期的输出结果:
396```ts
397JSVM InstanceOf:1
398```
399
400### OH_JSVM_TypeTagObject
401
402使用类型标签type_tag来标记JavaScript对象,这样在后续操作中可以更精确地识别JavaScript对象。
403
404### OH_JSVM_CheckObjectTypeTag
405
406检查给定的类型标签是否与对象上的类型标签匹配。
407
408cpp部分代码:
409
410```cpp
411// hello.cpp
412#include "napi/native_api.h"
413#include "ark_runtime/jsvm.h"
414#include <hilog/log.h>
415#define NUMBERINT_FOUR 4
416// 定义一个静态常量JSVM_TypeTag数组存储类型标签
417static const JSVM_TypeTag TagsData[NUMBERINT_FOUR] = {
418    {0x9e4b2449547061b3, 0x33999f8a6516c499},
419    {0x1d55a794c53a726d, 0x43633f509f9c944e},
420    {0, 0}, // 用于表示无标签或默认标签
421    {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0},
422};
423// OH_JSVM_TypeTagObject的样例方法
424static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info)
425{
426    // 获取两个JavaScript侧传入的参数
427    size_t argc = 2;
428    JSVM_Value args[2] = {nullptr};
429    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
430    // 获取索引数字转换为JSVM_Value
431    int32_t index = 0;
432    OH_JSVM_GetValueInt32(env, args[1], &index);
433    // 给参数(对象)设置类型标签
434    JSVM_Status status = OH_JSVM_TypeTagObject(env, args[0], &TagsData[index]);
435    // 将bool结果转换为JSVM_Value并返回
436    JSVM_Value result = nullptr;
437    if (status != JSVM_OK) {
438        OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail");
439        OH_JSVM_GetBoolean(env, false, &result);
440    } else {
441        OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success");
442        OH_JSVM_GetBoolean(env, true, &result);
443    }
444    return result;
445}
446// OH_JSVM_CheckObjectTypeTag的样例方法
447static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info)
448{
449    // 获取两个JavaScript侧传入的参数
450    size_t argc = 2;
451    JSVM_Value args[2] = {nullptr};
452    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
453    // 获取索引数字转换为JSVM_Value
454    int32_t index = 0;
455    OH_JSVM_GetValueInt32(env, args[1], &index);
456    // 检查对象的类型标签
457    bool checkResult = false;
458    JSVM_Status status = OH_JSVM_CheckObjectTypeTag(env, args[0], &TagsData[index], &checkResult);
459    if (status != JSVM_OK) {
460        OH_LOG_ERROR(LOG_APP, "JSVM CheckObjectTypeTag fail");
461    } else {
462        OH_LOG_INFO(LOG_APP, "JSVM CheckObjectTypeTag:%{public}d", checkResult);
463    }
464    // 将bool结果转换为JSVM_Value并返回
465    JSVM_Value checked = nullptr;
466    OH_JSVM_GetBoolean(env, checkResult, &checked);
467    return checked;
468}
469// SetTypeTagToObject,CheckObjectTypeTag注册回调
470static JSVM_CallbackStruct param[] = {
471    {.data = nullptr, .callback = SetTypeTagToObject},
472    {.data = nullptr, .callback = CheckObjectTypeTag},
473};
474static JSVM_CallbackStruct *method = param;
475// SetTypeTagToObject,CheckObjectTypeTag方法别名,TS侧调用
476static JSVM_PropertyDescriptor descriptor[] = {
477    {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
478    {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
479};
480// 样例测试js
481const char* srcCallNative = R"JS(
482         class Obj {
483           data;
484           message;
485         }
486         let obj= { data: 0, message: "hello world"};
487         setTypeTagToObject(obj, 0);
488         checkObjectTypeTag(obj,0);)JS";
489```
490<!-- @[oh_jsvm_check_object_type_tag](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/checkobjecttypetag/src/main/cpp/hello.cpp) -->
491
492预期的输出结果:
493```ts
494JSVM SetTypeTagToObject success
495JSVM CheckObjectTypeTag:1
496```
497
498### OH_JSVM_CreateExternal
499
500创建一个包装了外部指针的JavaScript对象。
501**注意**:JavaScript对象被垃圾回收时,包装的外部指针指向的内容不被GC直接管理,仅调用传入的第三个参数对应的函数(如果传入时不为nullptr)。
502
503cpp部分代码:
504
505```cpp
506// hello.cpp
507#include "napi/native_api.h"
508#include "ark_runtime/jsvm.h"
509#include <hilog/log.h>
510#include <fstream>
511// OH_JSVM_CreateExternal的样例方法
512static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info)
513{
514    size_t dataSize = 10;
515    void *data = malloc(dataSize);
516    if (data == nullptr) {
517        OH_LOG_ERROR(LOG_APP, "JSVM Failed to malloc.");
518        return nullptr;
519    }
520    memset(data, 0, dataSize);
521    const char* testStr = "test";
522    JSVM_Value external = nullptr;
523    JSVM_Status status = OH_JSVM_CreateExternal(
524        env, data, [](JSVM_Env env, void *data, void *hint) {free(data);}, (void *)testStr, &external);
525    if (status != JSVM_OK) {
526        OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status);
527        free(data);
528        data = nullptr;
529        return nullptr;
530    } else {
531        OH_LOG_INFO(LOG_APP, "JSVM CreateExternal success");
532    }
533    return external;
534}
535// CreateExternal注册回调
536static JSVM_CallbackStruct param[] = {
537    {.data = nullptr, .callback = CreateExternal},
538};
539static JSVM_CallbackStruct *method = param;
540// CreateExternal方法别名,供JS调用
541static JSVM_PropertyDescriptor descriptor[] = {
542    {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
543};
544// 样例测试js
545const char* srcCallNative = R"JS(createExternal())JS";
546```
547<!-- @[oh_jsvm_create_external](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/createexternal/src/main/cpp/hello.cpp) -->
548
549预期的输出结果:
550```ts
551JSVM CreateExternal success
552```
553
554### OH_JSVM_GetValueExternal
555
556OH_JSVM_CreateExternal可以创建并包装自定义的C/C++对象,并将其公开给JavaScript代码,而OH_JSVM_GetValueExternal则用于获取OH_JSVM_CreateExternal所包装的外部对象的指针。
557
558cpp部分代码:
559
560```cpp
561// hello.cpp
562#include "napi/native_api.h"
563#include "ark_runtime/jsvm.h"
564#include <hilog/log.h>
565// OH_JSVM_GetValueExternal的样例方法
566static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info)
567{
568    static int data = 0x12345;
569    JSVM_Value externalValue = nullptr;
570    JSVM_Status status = OH_JSVM_CreateExternal(env, (void*)&data, nullptr, nullptr, &externalValue);
571    if (status != JSVM_OK) {
572        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail");
573    } else {
574        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateExternal success");
575    }
576    void *data_value;
577    status = OH_JSVM_GetValueExternal(env, externalValue, &data_value);
578    if (status != JSVM_OK) {
579        OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail");
580    } else {
581        OH_LOG_INFO(LOG_APP, "JSVM GetValueExternal success");
582    }
583    // 将符号位转化为int类型传出去
584    JSVM_Value returnValue = nullptr;
585    int retData = *static_cast<int *>(data_value);
586    OH_JSVM_CreateInt32(env, retData, &returnValue);
587    return returnValue;
588}
589// GetValueExternal注册回调
590static JSVM_CallbackStruct param[] = {
591    {.data = nullptr, .callback = GetValueExternal},
592};
593static JSVM_CallbackStruct *method = param;
594// GetValueExternal方法别名,供JS调用
595static JSVM_PropertyDescriptor descriptor[] = {
596    {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
597};
598// 样例测试js
599const char* srcCallNative = R"JS(getValueExternal())JS";
600```
601<!-- @[oh_jsvm_get_value_external](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/getvalueexternal/src/main/cpp/hello.cpp) -->
602
603预期的输出结果:
604```ts
605JSVM OH_JSVM_CreateExternal success
606JSVM GetValueExternal success
607```
608
609### OH_JSVM_CreateSymbol
610
611用于创建一个新的Symbol。Symbol是一种特殊的数据类型,用于表示唯一的标识符。与字符串或数字不同,符号的值是唯一的,即使两个符号具有相同的描述,它们也是不相等的。符号通常用作对象属性的键,以确保属性的唯一性。
612
613cpp部分代码:
614
615```cpp
616// hello.cpp
617#include "napi/native_api.h"
618#include "ark_runtime/jsvm.h"
619#include <hilog/log.h>
620// OH_JSVM_CreateSymbol的样例方法
621static JSVM_Value CreateSymbol(JSVM_Env env, JSVM_CallbackInfo info)
622{
623    JSVM_Value result = nullptr;
624    const char *des = "only";
625    OH_JSVM_CreateStringUtf8(env, des, JSVM_AUTO_LENGTH, &result);
626    JSVM_Value returnSymbol = nullptr;
627    OH_JSVM_CreateSymbol(env, result, &returnSymbol);
628    JSVM_ValueType valuetypeSymbol;
629    OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol);
630    if (valuetypeSymbol == JSVM_SYMBOL) {
631        OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success");
632    } else {
633        OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol fail");
634    }
635    return returnSymbol;
636}
637// CreateSymbol注册回调
638static JSVM_CallbackStruct param[] = {
639    {.data = nullptr, .callback = CreateSymbol},
640};
641static JSVM_CallbackStruct *method = param;
642// CreateSymbol方法别名,供JS调用
643static JSVM_PropertyDescriptor descriptor[] = {
644    {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
645};
646// 样例测试js
647const char* srcCallNative = R"JS(createSymbol())JS";
648```
649<!-- @[oh_jsvm_create_symbol](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/createsymbol/src/main/cpp/hello.cpp) -->
650
651预期的输出结果:
652```ts
653JSVM CreateSymbol Success
654```
655
656### OH_JSVM_SymbolFor
657
658在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新Symbol。
659
660cpp部分代码:
661
662```cpp
663// hello.cpp
664#include "napi/native_api.h"
665#include "ark_runtime/jsvm.h"
666#include <hilog/log.h>
667// 定义一个常量,用于存储最大字符串长度
668static const int MAX_BUFFER_SIZE = 128;
669// OH_JSVM_SymbolFor的样例方法
670static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info)
671{
672    JSVM_Value description = nullptr;
673    OH_JSVM_CreateStringUtf8(env, "test_demo", 9, &description);
674    char buffer[MAX_BUFFER_SIZE];
675    size_t bufferSize = MAX_BUFFER_SIZE;
676    size_t copied = 0;
677    OH_JSVM_GetValueStringUtf8(env, description, buffer, bufferSize, &copied);
678    JSVM_Value symbol = nullptr;
679    OH_JSVM_CreateSymbol(env, description, &symbol);
680    JSVM_Value result_symbol = nullptr;
681    JSVM_Status status = OH_JSVM_SymbolFor(env, buffer, copied, &result_symbol);
682    JSVM_ValueType valuetypeSymbol;
683    OH_JSVM_Typeof(env, result_symbol, &valuetypeSymbol);
684    if (valuetypeSymbol == JSVM_SYMBOL && status == JSVM_OK) {
685        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SymbolFor success");
686    }
687    // 返回结果
688    return result_symbol;
689}
690// SymbolFor注册回调
691static JSVM_CallbackStruct param[] = {
692    {.data = nullptr, .callback = SymbolFor},
693};
694static JSVM_CallbackStruct *method = param;
695// SymbolFor方法别名,供JS调用
696static JSVM_PropertyDescriptor descriptor[] = {
697    {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
698};
699// 样例测试js
700const char* srcCallNative = R"JS(symbolFor())JS";
701```
702<!-- @[oh_jsvm_symbol_for](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutObject/symbolfor/src/main/cpp/hello.cpp) -->
703
704预期的输出结果:
705```ts
706JSVM OH_JSVM_SymbolFor success
707```
708