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注册回调 47static JSVM_CallbackStruct param[] = { 48 {.data = nullptr, .callback = GetPrototype}, 49}; 50static JSVM_CallbackStruct *method = param; 51// GetPrototype方法别名,供JS调用 52static JSVM_PropertyDescriptor descriptor[] = { 53 {"getPrototype", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 54}; 55// OH_JSVM_GetPrototype的样例方法 56static JSVM_Value GetPrototype(JSVM_Env env, JSVM_CallbackInfo info) 57{ 58 // 创建一个空对象 59 JSVM_Value obj = nullptr; 60 OH_JSVM_CreateObject(env, &obj); 61 const char *testNameStr = "set and get proto"; 62 JSVM_Value propValue = nullptr; 63 JSVM_Value key = nullptr; 64 OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &key); 65 OH_JSVM_CreateStringUtf8(env, testNameStr, strlen(testNameStr), &propValue); 66 OH_JSVM_SetProperty(env, obj, key, propValue); 67 // 获取属性 68 JSVM_Value propResult = nullptr; 69 JSVM_Status status = OH_JSVM_GetProperty(env, obj, key, &propResult); 70 if (status != JSVM_OK) { 71 OH_LOG_ERROR(LOG_APP, "JSVM GetPrototype fail"); 72 } else { 73 OH_LOG_INFO(LOG_APP, "JSVM GetPrototype success"); 74 } 75 return propResult; 76} 77``` 78 79ArkTS侧示例代码 80 81```ts 82import hilog from "@ohos.hilog" 83// 通过import的方式,引入Native能力。 84import napitest from "libentry.so" 85let script: string = `getPrototype()`; 86try { 87 let result = napitest.runJsVm(script); 88 hilog.info(0x0000, 'testJSVM', 'Test JSVM getPrototype: %{public}s', result); 89} catch (error) { 90 hilog.error(0x0000, 'testJSVM', 'Test JSVM getPrototype error: %{public}s', error.message); 91} 92``` 93 94### OH_JSVM_CreateObject 95 96创建一个默认的JavaScript Object对象。 97 98cpp部分代码 99 100```cpp 101// hello.cpp 102#include "napi/native_api.h" 103#include "ark_runtime/jsvm.h" 104#include <hilog/log.h> 105// CreateObject注册回调 106static JSVM_CallbackStruct param[] = { 107 {.data = nullptr, .callback = CreateObject}, 108}; 109static JSVM_CallbackStruct *method = param; 110// CreateObject方法别名,供JS调用 111static JSVM_PropertyDescriptor descriptor[] = { 112 {"createObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 113}; 114// OH_JSVM_CreateObject的样例方法 115static JSVM_Value CreateObject(JSVM_Env env, JSVM_CallbackInfo info) 116{ 117 JSVM_Value object = nullptr; 118 // 创建一个空对象 119 JSVM_Status status = OH_JSVM_CreateObject(env, &object); 120 if (status != JSVM_OK) { 121 OH_LOG_ERROR(LOG_APP, "JSVM CreateObject fail"); 122 } else { 123 OH_LOG_INFO(LOG_APP, "JSVM CreateObject success"); 124 } 125 // 设置对象的属性 126 JSVM_Value name = nullptr; 127 // 设置属性名为 "name" 128 OH_JSVM_CreateStringUtf8(env, "name", JSVM_AUTO_LENGTH, &name); 129 JSVM_Value value = nullptr; 130 // 设置属性值为 "Hello from N-API!" 131 OH_JSVM_CreateStringUtf8(env, "Hello OH_JSVM_CreateObject!", JSVM_AUTO_LENGTH, &value); 132 // 将属性设置到对象上 133 OH_JSVM_SetProperty(env, object, name, value); 134 return object; 135} 136``` 137 138ArkTS侧示例代码 139 140```ts 141import hilog from "@ohos.hilog" 142// 通过import的方式,引入Native能力。 143import napitest from "libentry.so" 144let script: string = `createObject()`; 145try { 146 let result = napitest.runJsVm(script); 147 hilog.info(0x0000, 'testJSVM', 'Test JSVM createObject: %{public}s', result); 148} catch (error) { 149 hilog.error(0x0000, 'testJSVM', 'Test JSVM createObject error: %{public}s', error.message); 150} 151``` 152 153### OH_JSVM_ObjectFreeze 154 155冻结给定的对象,防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。 156 157cpp部分代码 158 159```cpp 160// hello.cpp 161#include "napi/native_api.h" 162#include "ark_runtime/jsvm.h" 163#include <hilog/log.h> 164// ObjectFreeze注册回调 165static JSVM_CallbackStruct param[] = { 166 {.data = nullptr, .callback = ObjectFreeze}, 167}; 168static JSVM_CallbackStruct *method = param; 169// ObjectFreeze方法别名,供JS调用 170static JSVM_PropertyDescriptor descriptor[] = { 171 {"objectFreeze", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 172}; 173// OH_JSVM_ObjectFreeze的样例方法 174static JSVM_Value ObjectFreeze(JSVM_Env env, JSVM_CallbackInfo info) 175{ 176 // 接受一个JavaScript侧传入的object 177 size_t argc = 1; 178 JSVM_Value argv[1] = {nullptr}; 179 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 180 // 调用接口OH_JSVM_ObjectFreeze将传入的object冻结 181 JSVM_Status status = OH_JSVM_ObjectFreeze(env, argv[0]); 182 if (status == JSVM_OK) { 183 OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectFreeze success"); 184 } 185 // 测试冻结后的对象中属性能否修改 186 JSVM_Value value = nullptr; 187 OH_JSVM_CreateInt32(env, 111111, &value); 188 OH_JSVM_SetNamedProperty(env, argv[0], "data", value); 189 // 将冻结后修改过的属性返回JavaScript侧 190 return argv[0]; 191} 192``` 193 194ArkTS侧示例代码 195 196```ts 197import hilog from "@ohos.hilog" 198// 通过import的方式,引入Native能力。 199import napitest from "libentry.so" 200let script: string = ` 201 let obj = { data: 55, message: "hello world"}; 202 objectFreeze(obj) 203` 204try { 205 let result = napitest.runJsVm(script); 206 // 冻结后的对象还是之前的属性值并未修改 207 hilog.info(0x0000, 'testJSVM', 'Test JSVM objectFreeze: %{public}s', result); 208} catch (error) { 209 hilog.error(0x0000, 'testJSVM', 'Test JSVM objectFreeze error: %{public}s', error.message); 210} 211``` 212 213### OH_JSVM_ObjectSeal 214 215密封给定的对象。这可以防止向其添加新属性,以及将所有现有属性标记为不可配置。 216 217cpp部分代码 218 219```cpp 220// hello.cpp 221#include "napi/native_api.h" 222#include "ark_runtime/jsvm.h" 223#include <hilog/log.h> 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// OH_JSVM_ObjectSeal的样例方法 234static JSVM_Value ObjectSeal(JSVM_Env env, JSVM_CallbackInfo info) 235{ 236 // 接受一个JavaScript侧传入的object 237 size_t argc = 1; 238 JSVM_Value argv[1] = {nullptr}; 239 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 240 // 调用接口OH_JSVM_ObjectSeal将传入的object封闭,使其无法添加新的属性 241 JSVM_Status status = OH_JSVM_ObjectSeal(env, argv[0]); 242 if (status == JSVM_OK) { 243 OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal success"); 244 } 245 // 检查封闭后的对象中属性能否修改、删除、新增 246 // 封闭后对象修改 247 JSVM_Value changeValue = nullptr; 248 OH_JSVM_CreateInt32(env, 111111, &changeValue); 249 OH_JSVM_SetNamedProperty(env, argv[0], "data", changeValue); 250 // 封闭后对象删除 251 JSVM_Value deleteProperty = nullptr; 252 OH_JSVM_CreateStringUtf8(env, "message", JSVM_AUTO_LENGTH, &deleteProperty); 253 bool result = false; 254 OH_JSVM_DeleteProperty(env, argv[0], deleteProperty, &result); 255 if (result) { 256 OH_LOG_INFO(LOG_APP, "Test JSVM OH_JSVM_ObjectSeal failed"); 257 } 258 // 封闭后对象新增 259 JSVM_Value addValue = nullptr; 260 OH_JSVM_CreateStringUtf8(env, "addValue", JSVM_AUTO_LENGTH, &addValue); 261 OH_JSVM_SetNamedProperty(env, argv[0], "newProperty", addValue); 262 // 将封闭后改动过的对象返回JavaScript侧 263 return argv[0]; 264} 265``` 266 267ArkTS侧示例代码 268 269```ts 270import hilog from "@ohos.hilog" 271// 通过import的方式,引入Native能力。 272import napitest from "libentry.so" 273let script: string = ` 274 let obj = { data: 55, message: "hello world"}; 275 objectSeal(obj) 276` 277try { 278 let result = napitest.runJsVm(script); 279 // 封闭后的对象输出后显示可以修改但不能删除和新增 280 hilog.info(0x0000, 'testJSVM', 'Test JSVM objectSeal: %{public}s', result); 281} catch (error) { 282 hilog.error(0x0000, 'testJSVM', 'Test JSVM objectSeal error: %{public}s', error.message); 283} 284``` 285 286### OH_JSVM_Typeof 287 288返回JavaScript对象的类型。 289 290cpp部分代码 291 292```cpp 293// hello.cpp 294#include "napi/native_api.h" 295#include "ark_runtime/jsvm.h" 296#include <hilog/log.h> 297// GetTypeof注册回调 298static JSVM_CallbackStruct param[] = { 299 {.data = nullptr, .callback = GetTypeof}, 300}; 301static JSVM_CallbackStruct *method = param; 302// GetTypeof方法别名,TS侧调用 303static JSVM_PropertyDescriptor descriptor[] = { 304 {"getTypeof", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 305}; 306// OH_JSVM_Typeof的样例方法 307static JSVM_Value GetTypeof(JSVM_Env env, JSVM_CallbackInfo info) { 308 size_t argc = 1; 309 JSVM_Value args[1] = {nullptr}; 310 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 311 JSVM_ValueType valueType; 312 OH_JSVM_Typeof(env, args[0], &valueType); 313 JSVM_Value type = nullptr; 314 switch (valueType) { 315 case JSVM_UNDEFINED: 316 OH_LOG_INFO(LOG_APP, "JSVM Input type is undefined"); 317 OH_JSVM_CreateStringUtf8(env, "Input type is undefined", JSVM_AUTO_LENGTH, &type); 318 break; 319 case JSVM_NULL: 320 OH_LOG_INFO(LOG_APP, "JSVM Input type is null"); 321 OH_JSVM_CreateStringUtf8(env, "Input type is null", JSVM_AUTO_LENGTH, &type); 322 break; 323 case JSVM_BOOLEAN: 324 OH_LOG_INFO(LOG_APP, "JSVM Input type is boolean"); 325 OH_JSVM_CreateStringUtf8(env, "Input type is boolean", JSVM_AUTO_LENGTH, &type); 326 break; 327 case JSVM_NUMBER: 328 OH_LOG_INFO(LOG_APP, "JSVM Input type is number"); 329 OH_JSVM_CreateStringUtf8(env, "Input type is number", JSVM_AUTO_LENGTH, &type); 330 break; 331 case JSVM_STRING: 332 OH_LOG_INFO(LOG_APP, "JSVM Input type is string"); 333 OH_JSVM_CreateStringUtf8(env, "Input type is string", JSVM_AUTO_LENGTH, &type); 334 break; 335 case JSVM_SYMBOL: 336 OH_LOG_INFO(LOG_APP, "JSVM Input type is symbol"); 337 OH_JSVM_CreateStringUtf8(env, "Input type is symbol", JSVM_AUTO_LENGTH, &type); 338 break; 339 case JSVM_OBJECT: 340 OH_LOG_INFO(LOG_APP, "JSVM Input type is object"); 341 OH_JSVM_CreateStringUtf8(env, "Input type is object", JSVM_AUTO_LENGTH, &type); 342 break; 343 case JSVM_FUNCTION: 344 OH_LOG_INFO(LOG_APP, "JSVM Input type is function"); 345 OH_JSVM_CreateStringUtf8(env, "Input type is function", JSVM_AUTO_LENGTH, &type); 346 break; 347 case JSVM_EXTERNAL: 348 OH_LOG_INFO(LOG_APP, "JSVM Input type is external"); 349 OH_JSVM_CreateStringUtf8(env, "Input type is external", JSVM_AUTO_LENGTH, &type); 350 break; 351 case JSVM_BIGINT: 352 OH_LOG_INFO(LOG_APP, "JSVM Input type is bigint"); 353 OH_JSVM_CreateStringUtf8(env, "Input type is bigint", JSVM_AUTO_LENGTH, &type); 354 break; 355 default: 356 OH_LOG_INFO(LOG_APP, "JSVM Input type does not match any"); 357 OH_JSVM_CreateStringUtf8(env, " ", JSVM_AUTO_LENGTH, &type); 358 break; 359 } 360 return type; 361} 362``` 363 364ArkTS侧示例代码 365 366```ts 367import hilog from "@ohos.hilog" 368// 通过import的方式,引入Native能力。 369import napitest from "libentry.so" 370let script: string = ` 371getTypeof(true); 372 `; 373try { 374 let result = napitest.runJsVm(script); 375 hilog.info(0x0000, 'JSVM', 'GetTypeof: %{public}s', result); 376} catch (error) { 377 hilog.error(0x0000, 'JSVM', 'GetTypeof: %{public}s', error.message); 378} 379``` 380 381### OH_JSVM_Instanceof 382 383判断一个对象是否是某个构造函数的实例。 384 385cpp部分代码 386 387```cpp 388// hello.cpp 389#include "napi/native_api.h" 390#include "ark_runtime/jsvm.h" 391#include <hilog/log.h> 392// InstanceOf注册回调 393static JSVM_CallbackStruct param[] = { 394 {.data = nullptr, .callback = InstanceOf}, 395}; 396static JSVM_CallbackStruct *method = param; 397// InstanceOf方法别名,TS侧调用 398static JSVM_PropertyDescriptor descriptor[] = { 399 {"instanceOf", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 400}; 401// OH_JSVM_Instanceof的样例方法 402static JSVM_Value InstanceOf(JSVM_Env env, JSVM_CallbackInfo info) 403{ 404 // 获取两个JavaScript侧传入的参数 405 size_t argc = 2; 406 JSVM_Value args[2] = {nullptr}; 407 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 408 bool result = false; 409 JSVM_Status status = OH_JSVM_Instanceof(env, args[0], args[1], &result); 410 if (status != JSVM_OK) { 411 OH_LOG_ERROR(LOG_APP, "JSVM InstanceOf fail"); 412 } else { 413 OH_LOG_INFO(LOG_APP, "JSVM InstanceOf:%{public}d", result); 414 } 415 JSVM_Value returnValue = nullptr; 416 OH_JSVM_GetBoolean(env, result, &returnValue); 417 return returnValue; 418} 419``` 420 421ArkTS侧示例代码 422 423```ts 424import hilog from "@ohos.hilog" 425// 通过import的方式,引入Native能力。 426import napitest from "libentry.so" 427let script: string = ` 428 class Person { 429 name; 430 age; 431 constructor(name, age) { 432 this.name = name; 433 this.age = age; 434 } 435 } 436 instanceOf(new Person('Alice', 30), Person); 437 ; 438 `; 439try { 440 let result = napitest.runJsVm(script.toString()); 441 hilog.info(0x0000, 'JSVM', 'InstanceOf: %{public}s', result); 442} catch (error) { 443 hilog.error(0x0000, 'JSVM', 'InstanceOf: %{public}s', error.message); 444} 445``` 446 447### OH_JSVM_TypeTagObject 448 449使用类型标签type_tag来标记JavaScript对象,后续可以更精确地识别JavaScript对象。 450 451### OH_JSVM_CheckObjectTypeTag 452 453检查给定的类型标签是否与对象上的类型标签匹配。 454 455cpp部分代码 456 457```cpp 458// hello.cpp 459#include "napi/native_api.h" 460#include "ark_runtime/jsvm.h" 461#include <hilog/log.h> 462// SetTypeTagToObject,CheckObjectTypeTag注册回调 463static JSVM_CallbackStruct param[] = { 464 {.data = nullptr, .callback = SetTypeTagToObject}, 465 {.data = nullptr, .callback = CheckObjectTypeTag}, 466}; 467static JSVM_CallbackStruct *method = param; 468// SetTypeTagToObject,CheckObjectTypeTag方法别名,TS侧调用 469static JSVM_PropertyDescriptor descriptor[] = { 470 {"setTypeTagToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 471 {"checkObjectTypeTag", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 472}; 473#define NUMBERINT_FOUR 4 474// 定义一个静态常量JSVM_TypeTag数组存储类型标签 475static const JSVM_TypeTag TagsData[NUMBERINT_FOUR] = { 476 {0x9e4b2449547061b3, 0x33999f8a6516c499}, 477 {0x1d55a794c53a726d, 0x43633f509f9c944e}, 478 {0, 0}, // 用于表示无标签或默认标签 479 {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0}, 480}; 481// OH_JSVM_TypeTagObject的样例方法 482static JSVM_Value SetTypeTagToObject(JSVM_Env env, JSVM_CallbackInfo info) 483{ 484 // 获取两个JavaScript侧传入的参数 485 size_t argc = 2; 486 JSVM_Value args[2] = {nullptr}; 487 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 488 // 获取索引数字转换为JSVM_Value 489 int32_t index = 0; 490 OH_JSVM_GetValueInt32(env, args[1], &index); 491 // 给参数(对象)设置类型标签 492 JSVM_Status status = OH_JSVM_TypeTagObject(env, args[0], &TagsData[index]); 493 if (status != JSVM_OK) { 494 OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail"); 495 } else { 496 OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject success"); 497 } 498 // 将bool结果转换为JSVM_Value并返回 499 JSVM_Value result = nullptr; 500 OH_JSVM_GetBoolean(env, true, &result); 501 return result; 502} 503// OH_JSVM_CheckObjectTypeTag的样例方法 504static JSVM_Value CheckObjectTypeTag(JSVM_Env env, JSVM_CallbackInfo info) 505{ 506 // 获取两个JavaScript侧传入的参数 507 size_t argc = 2; 508 JSVM_Value args[2] = {nullptr}; 509 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 510 // 获取索引数字转换为JSVM_Value 511 int32_t index = 0; 512 OH_JSVM_GetValueInt32(env, args[1], &index); 513 // 检查对象的类型标签 514 bool checkResult = false; 515 JSVM_Status status = OH_JSVM_CheckObjectTypeTag(env, args[0], &TagsData[index], &checkResult); 516 if (status != JSVM_OK) { 517 OH_LOG_ERROR(LOG_APP, "JSVM SetTypeTagToObject fail"); 518 } else { 519 OH_LOG_INFO(LOG_APP, "JSVM SetTypeTagToObject:%{public}d", checkResult); 520 } 521 // 将bool结果转换为JSVM_Value并返回 522 JSVM_Value checked = nullptr; 523 OH_JSVM_GetBoolean(env, checkResult, &checked); 524 return checked; 525} 526``` 527 528ArkTS侧示例代码 529 530```ts 531import hilog from "@ohos.hilog" 532// 通过import的方式,引入Native能力。 533import napitest from "libentry.so" 534let script: string = ` 535 class Obj { 536 data; 537 message; 538 } 539 let obj= { data: 0, message: "hello world"}; 540 setTypeTagToObject(obj, 0) 541 ` 542try { 543 let result = napitest.runJsVm(script); 544 hilog.info(0x0000, 'JSVM', 'SetTypeTagToObject: %{public}s', result); 545} catch (error) { 546 hilog.error(0x0000, 'JSVM', 'SetTypeTagToObject: %{public}s', error.message); 547} 548let script: string = ` 549 class Obj { 550 data; 551 message; 552 } 553 let obj= { data: 0, message: "hello world"}; 554 setTypeTagToObject(obj,0) 555 checkObjectTypeTag(obj,0); 556 ` 557try { 558 let result = napitest.runJsVm(script); 559 hilog.info(0x0000, 'JSVM', 'CheckObjectTypeTag: %{public}s', result); 560} catch (error) { 561 hilog.error(0x0000, 'JSVM', 'CheckObjectTypeTag: %{public}s', error.message); 562} 563``` 564 565### OH_JSVM_CreateExternal 566 567创建一个包装了外部指针的JavaScript对象 568 569cpp部分代码 570 571```cpp 572// hello.cpp 573#include "napi/native_api.h" 574#include "ark_runtime/jsvm.h" 575#include <hilog/log.h> 576// CreateExternal注册回调 577static JSVM_CallbackStruct param[] = { 578 {.data = nullptr, .callback = CreateExternal}, 579}; 580static JSVM_CallbackStruct *method = param; 581// CreateExternal方法别名,供JS调用 582static JSVM_PropertyDescriptor descriptor[] = { 583 {"createExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 584}; 585// OH_JSVM_CreateExternal的样例方法 586static JSVM_Value CreateExternal(JSVM_Env env, JSVM_CallbackInfo info) 587{ 588 size_t dataSize = 10; 589 void *data = malloc(dataSize); 590 memset(data, 0, dataSize); 591 const char testStr[] = "test"; 592 JSVM_Value external = nullptr; 593 JSVM_Status status = OH_JSVM_CreateExternal( 594 env, (void *)testStr, [](JSVM_Env env, void *data, void *hint) {}, (void *)testStr, &external); 595 JSVM_Value returnValue = nullptr; 596 bool type = false; 597 if (status != JSVM_OK) { 598 OH_LOG_ERROR(LOG_APP, "JSVM Failed to create external data, status:%{public}d.", status); 599 return nullptr; 600 } else { 601 type = true; 602 OH_LOG_INFO(LOG_APP, "JSVM CreateExternal:%{public}d", type); 603 } 604 OH_JSVM_GetBoolean(env, type, &returnValue); 605 // 返回结果 606 return returnValue; 607} 608``` 609 610ArkTS侧示例代码 611 612```ts 613import hilog from "@ohos.hilog" 614// 通过import的方式,引入Native能力。 615import napitest from "libentry.so" 616let script: string = `createExternal()`; 617try { 618 let result = napitest.runJsVm(script); 619 hilog.info(0x0000, 'testJSVM', 'Test JSVM createExternal: %{public}s', result); 620} catch (error) { 621 hilog.error(0x0000, 'testJSVM', 'Test JSVM createExternal error: %{public}s', error.message); 622} 623``` 624 625### OH_JSVM_GetValueExternal 626 627OH_JSVM_CreateExternal可以创建包装自定义的C/C++对象并将其公开给JavaScript代码,而OH_JSVM_GetValueExternal就是用来获得OH_JSVM_CreateExternal所创建的外部对象的。 628 629cpp部分代码 630 631```cpp 632// hello.cpp 633#include "napi/native_api.h" 634#include "ark_runtime/jsvm.h" 635#include <hilog/log.h> 636// GetValueExternal注册回调 637static JSVM_CallbackStruct param[] = { 638 {.data = nullptr, .callback = GetValueExternal}, 639}; 640static JSVM_CallbackStruct *method = param; 641// GetValueExternal方法别名,供JS调用 642static JSVM_PropertyDescriptor descriptor[] = { 643 {"getValueExternal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 644}; 645// OH_JSVM_GetValueExternal的样例方法 646static JSVM_Value GetValueExternal(JSVM_Env env, JSVM_CallbackInfo info) 647{ 648 void *data = (void *)0x12345; 649 JSVM_Value externalValue = nullptr; 650 JSVM_Status status = OH_JSVM_CreateExternal(env, data, nullptr, nullptr, &externalValue); 651 if (status != JSVM_OK) { 652 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateExternal fail"); 653 } 654 void *data_value; 655 status = OH_JSVM_GetValueExternal(env, externalValue, &data_value); 656 bool type = false; 657 if (status != JSVM_OK) { 658 OH_LOG_ERROR(LOG_APP, "JSVM GetValueExternal fail"); 659 } 660 type = true; 661 OH_LOG_INFO(LOG_APP, "JSVM API Get ValueExternal:%{public}p", data_value); 662 // 将符号位转化为int类型传出去 663 JSVM_Value returnValue = nullptr; 664 OH_JSVM_CreateInt32(env, 0, &returnValue); 665 return returnValue; 666} 667``` 668 669ArkTS侧示例代码 670 671```ts 672import hilog from "@ohos.hilog" 673// 通过import的方式,引入Native能力。 674import napitest from "libentry.so" 675let script: string = `getValueExternal()`; 676try { 677 let result = napitest.runJsVm(script); 678 hilog.info(0x0000, 'testJSVM', 'Test JSVM getValueExternal: %{public}s', result); 679} catch (error) { 680 hilog.error(0x0000, 'testJSVM', 'Test JSVM getValueExternal error: %{public}s', error.message); 681} 682``` 683 684### OH_JSVM_CreateSymbol 685 686用于创建一个新的Symbol。Symbol是一种特殊的数据类型,用于表示唯一的标识符。与字符串或数字不同,符号的值是唯一的,即使两个符号具有相同的描述,它们也是不相等的。符号通常用作对象属性的键,以确保属性的唯一性。 687 688cpp部分代码 689 690```cpp 691// hello.cpp 692#include "napi/native_api.h" 693#include "ark_runtime/jsvm.h" 694#include <hilog/log.h> 695// CreateSymbol注册回调 696static JSVM_CallbackStruct param[] = { 697 {.data = nullptr, .callback = CreateSymbol}, 698}; 699static JSVM_CallbackStruct *method = param; 700// CreateSymbol方法别名,供JS调用 701static JSVM_PropertyDescriptor descriptor[] = { 702 {"createSymbol", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 703}; 704// OH_JSVM_CreateSymbol的样例方法 705static JSVM_Value CreateSymbol(JSVM_Env env, JSVM_CallbackInfo info) 706{ 707 JSVM_Value result = nullptr; 708 const char *des = "only"; 709 OH_JSVM_CreateStringUtf8(env, des, JSVM_AUTO_LENGTH, &result); 710 JSVM_Value returnSymbol = nullptr; 711 OH_JSVM_CreateSymbol(env, result, &returnSymbol); 712 JSVM_Value returnValue = nullptr; 713 bool type = false; 714 JSVM_ValueType valuetypeSymbol; 715 OH_JSVM_Typeof(env, returnSymbol, &valuetypeSymbol); 716 if (valuetypeSymbol == JSVM_SYMBOL) { 717 OH_LOG_INFO(LOG_APP, "JSVM CreateSymbol Success"); 718 type = true; 719 } 720 OH_JSVM_GetBoolean(env, type, &returnValue); 721 return returnValue; 722} 723``` 724 725ArkTS侧示例代码 726 727```ts 728import hilog from "@ohos.hilog" 729// 通过import的方式,引入Native能力。 730import napitest from "libentry.so" 731let script: string = `createSymbol()`; 732try { 733 let result = napitest.runJsVm(script); 734 hilog.info(0x0000, 'testJSVM', 'Test JSVM createSymbol: %{public}s', result); 735} catch (error) { 736 hilog.error(0x0000, 'testJSVM', 'Test JSVM createSymbol error: %{public}s', error.message); 737} 738``` 739 740### OH_JSVM_SymbolFor 741 742在全局注册表中搜索具有给定描述的现有Symbol,如果该Symbol已经存在,它将被返回,否则将在注册表中创建一个新Symbol 743 744cpp部分代码 745 746```cpp 747// hello.cpp 748#include "napi/native_api.h" 749#include "ark_runtime/jsvm.h" 750#include <hilog/log.h> 751// SymbolFor注册回调 752static JSVM_CallbackStruct param[] = { 753 {.data = nullptr, .callback = SymbolFor}, 754}; 755static JSVM_CallbackStruct *method = param; 756// SymbolFor方法别名,供JS调用 757static JSVM_PropertyDescriptor descriptor[] = { 758 {"symbolFor", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 759}; 760// 定义一个常量,用于存储最大字符串长度 761static const int MAX_BUFFER_SIZE = 128; 762// OH_JSVM_SymbolFor的样例方法 763static JSVM_Value SymbolFor(JSVM_Env env, JSVM_CallbackInfo info) 764{ 765 JSVM_Value description = nullptr; 766 OH_JSVM_CreateStringUtf8(env, "test_demo", 9, &description); 767 char buffer[MAX_BUFFER_SIZE]; 768 size_t bufferSize = MAX_BUFFER_SIZE; 769 size_t copied = 0; 770 OH_JSVM_GetValueStringUtf8(env, description, buffer, bufferSize, &copied); 771 JSVM_Value symbol = nullptr; 772 OH_JSVM_CreateSymbol(env, description, &symbol); 773 JSVM_Value result_symbol = nullptr; 774 JSVM_Status status = OH_JSVM_SymbolFor(env, nullptr, 0, &result_symbol); 775 JSVM_Value returnValue = nullptr; 776 bool type = false; 777 JSVM_ValueType valuetypeSymbol; 778 OH_JSVM_Typeof(env, result_symbol, &valuetypeSymbol); 779 if (valuetypeSymbol == JSVM_SYMBOL && status == JSVM_OK) { 780 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_SymbolFor success"); 781 type = true; 782 } 783 OH_JSVM_GetBoolean(env, type, &returnValue); 784 // 返回结果 785 return returnValue; 786} 787``` 788 789ArkTS侧示例代码 790 791```ts 792import hilog from "@ohos.hilog" 793// 通过import的方式,引入Native能力。 794import napitest from "libentry.so" 795let script: string = `symbolFor()`; 796try { 797 let result = napitest.runJsVm(script); 798 hilog.info(0x0000, 'testJSVM', 'Test JSVM symbolFor: %{public}s', result); 799} catch (error) { 800 hilog.error(0x0000, 'testJSVM', 'Test JSVM symbolFor error: %{public}s', error.message); 801} 802``` 803