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