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