1# 使用JSVM-API接口进行array相关开发 2 3## 简介 4 5使用 JSVM-API 接口进行数组(array)相关开发时,调用相关接口可以在 JSVM 模块中直接操作和处理 JavaScript 中的数组。 6 7## 基本概念 8 9使用 JSVM-API 接口进行数组(array)相关开发时,涉及的基本概念主要包括数组的创建、访问、修改、遍历以及与数组相关的操作。这些概念对于理解在 JSVM 模块中如何与 JavaScript 数组交互非常重要。以下是一些关键概念: 10 11- **数组的创建**:若在 JSVM 模块中需要创建一个新的 JavaScript 数组,可以使用提供的 OH_JSVM_CreateArray 接口创建数组,将数组传递给 JavaScript 层。 12- **数组相关操作**:在 JSVM 模块中通过对应的接口获取 JavaScript 数组的长度、检索指定索引处的元素以及设置指定索引处的元素值,从而实现 JSVM 模块与 JavaScript 数组的交互。 13- **TypedArray**:JavaScript 中的 TypedArray 是一种用来描述二进制数据的类数组数据视图,可以简单理解为一种指定元素类型的数组,TypedArray 没有直接构造器,但是可以用它的子类构造器构造 TypedArray 类型的数据。TypedArray 的子类有:Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Int32Array 等。 14- **ArrayBuffer**:ArrayBuffer 是固定长度的二进制数据缓冲区。 15- **DataView**:DataView 是 JavaScript 中的一种视图,是可以从 ArrayBuffer 对象中读写多种数值类型的底层接口。 16 17 18## 接口说明 19 20| 接口 | 功能说明 | 21| ---------------------------- | ------------------------------------------ | 22|OH_JSVM_CreateArray | 创建一个新的 JavaScript 数组对象 | 23|OH_JSVM_CreateArrayWithLength | 创建一个指定长度的 JavaScript 数组对象 | 24|OH_JSVM_CreateTypedarray | 在现有的 ArrayBuffer 上创建一个 JavaScript TypedArray 对象,TypedArray 对象在底层数据缓冲区上提供类似数组的视图,其中每个元素都具有相同的底层二进制标量数据类型。需要注意,对于入参有以下要求:(length * size_of_element) + byte_offset 要不大于传入数组的大小(以字节为单位),size_of_element 指数组中元素的数据类型的大小,否则会引发 RangeError 异常。| 25|OH_JSVM_CreateDataview | 在现有的 ArrayBuffer 上创建一个 JavaScript DataView 对象,DataView 对象在底层数据缓冲区上提供类似数组的视图,该 ArrayBuffer 允许有不同大小和类型的元素。要求 byte_length + byte_offset 小于或等于传入数组的字节大小,否则会引发 RangeError 异常。| 26|OH_JSVM_GetArrayLength | 返回 Array 对象的长度 | 27|OH_JSVM_GetTypedarrayInfo | 获取 TypedArray(类型化数组)对象的信息 | 28|OH_JSVM_GetDataviewInfo | 获取 Dataview 对象的信息 | 29|OH_JSVM_IsArray | 判断一个 JavaScript 对象是否为 Array 类型对象| 30|OH_JSVM_SetElement | 在给定对象的指定索引处设置元素 | 31|OH_JSVM_GetElement | 获取给定对象指定索引处的元素 | 32|OH_JSVM_HasElement | 若给定对象的指定索引处拥有属性,获取该元素 | 33|OH_JSVM_DeleteElement | 尝试删除给定对象的指定索引处的元素 | 34|OH_JSVM_IsDataview | 判断一个 JavaScript 对象是否为 Dataview 类型对象 | 35|OH_JSVM_IsTypedarray | 判断一个 JavaScript 对象是否为 Typedarray 类型对象 | 36 37## 使用示例 38 39JSVM-API 接口开发流程参考[使用 JSVM-API 实现 JS 与 C/C++ 语言交互开发流程](use-jsvm-process.md),本文仅对接口对应 C++ 相关代码进行展示。 40 41### OH_JSVM_CreateArray 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// CreateArray注册回调 53static int DIFF_VALUE_FIVE = 5; 54// OH_JSVM_CreateArray的样例方法 55static JSVM_Value CreateArray(JSVM_Env env, JSVM_CallbackInfo info) 56{ 57 // 创建一个空数组 58 JSVM_Value array = nullptr; 59 JSVM_Status status = OH_JSVM_CreateArray(env, &array); 60 // 对创建的数组进行赋值 61 for (int i = 0; i < DIFF_VALUE_FIVE; i++) { 62 JSVM_Value element; 63 OH_JSVM_CreateInt32(env, i, &element); 64 OH_JSVM_SetElement(env, array, i, element); 65 } 66 if (status != JSVM_OK) { 67 OH_LOG_ERROR(LOG_APP, "JSVM CreateArray fail"); 68 } else { 69 OH_LOG_INFO(LOG_APP, "JSVM CreateArray success"); 70 } 71 return array; 72} 73static JSVM_CallbackStruct param[] = { 74 {.data = nullptr, .callback = CreateArray}, 75}; 76static JSVM_CallbackStruct *method = param; 77// CreateArray方法别名,供JS调用 78static JSVM_PropertyDescriptor descriptor[] = { 79 {"createArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 80}; 81// 样例测试js 82const char *srcCallNative = R"JS( 83 function testCreateArray() { 84 return createArray(); 85 } 86 testCreateArray(); 87)JS"; 88``` 89### OH_JSVM_CreateArrayWithLength 90 91创建一个指定长度的 JavaScript 数组对象。 92 93cpp 部分代码: 94 95```cpp 96// hello.cpp 97#include "napi/native_api.h" 98#include "ark_runtime/jsvm.h" 99#include <hilog/log.h> 100// OH_JSVM_CreateArrayWithLength的样例方法 101static JSVM_Value CreateArrayWithLength(JSVM_Env env, JSVM_CallbackInfo info) 102{ 103 size_t argc = 1; 104 JSVM_Value argv[1] = {nullptr}; 105 JSVM_Value result = nullptr; 106 // 解析传递的参数OH_JSVM_GetCbInfo 107 OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); 108 // 获取传递的数组长度 109 int32_t length; 110 OH_JSVM_GetValueInt32(env, argv[0], &length); 111 // 使用OH_JSVM_CreateArrayWithLength创建传递固定长度的数组 112 JSVM_Status status = OH_JSVM_CreateArrayWithLength(env, length, &result); 113 if (status == JSVM_OK) { 114 // 给创建的数组设置值 115 for (int32_t i = 0; i < length; i++) { 116 JSVM_Value value; 117 OH_JSVM_CreateInt32(env, i, &value); 118 OH_JSVM_SetElement(env, result, i, value); 119 } 120 OH_LOG_INFO(LOG_APP, "JSVM CreateArrayWithLength success"); 121 } else { 122 OH_LOG_ERROR(LOG_APP, "JSVM CreateArrayWithLength fail"); 123 } 124 return result; 125} 126// CreateArrayWithLength注册回调 127static JSVM_CallbackStruct param[] = { 128 {.data = nullptr, .callback = CreateArrayWithLength}, 129}; 130static JSVM_CallbackStruct *method = param; 131// CreateArrayWithLength方法别名,供JS调用 132static JSVM_PropertyDescriptor descriptor[] = { 133 {"createArrayWithLength", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 134}; 135// 样例测试js 136const char *srcCallNative = R"JS( 137let num = 7; 138function testCreateArrayWithLength(num){ 139 return createArrayWithLength(num); 140} 141testCreateArrayWithLength(num); 142)JS"; 143``` 144 145### OH_JSVM_CreateTypedarray 146 147在现有的 ArrayBuffer上 创建一个 JavaScript TypedArray 对象,TypedArray 对象在底层数据缓冲区上提供类似数组的视图,其中每个元素都具有相同的底层二进制标量数据类型。 148 149cpp 部分代码 150 151```cpp 152// hello.cpp 153#include "napi/native_api.h" 154#include "ark_runtime/jsvm.h" 155#include <hilog/log.h> 156// OH_JSVM_CreateTypedarray的样例方法 157static int DIFF_VALUE_THREE = 3; 158static JSVM_Value CreateTypedArray(JSVM_Env env, JSVM_CallbackInfo info) 159{ 160 size_t argc = 1; 161 JSVM_Value args[1] = {nullptr}; 162 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 163 int32_t typeNum; 164 OH_JSVM_GetValueInt32(env, args[0], &typeNum); 165 JSVM_TypedarrayType arrayType; 166 // 用于存储每个元素的大小 167 size_t elementSize = 0; 168 // 转换为JSVM_TypedarrayType类型 169 arrayType = static_cast<JSVM_TypedarrayType>(typeNum); 170 switch (typeNum) { 171 case JSVM_INT8_ARRAY: 172 case JSVM_UINT8_ARRAY: 173 case JSVM_UINT8_CLAMPED_ARRAY: 174 elementSize = sizeof(int8_t); 175 break; 176 case JSVM_INT16_ARRAY: 177 case JSVM_UINT16_ARRAY: 178 elementSize = sizeof(int16_t); 179 break; 180 case JSVM_INT32_ARRAY: 181 case JSVM_UINT32_ARRAY: 182 elementSize = sizeof(int32_t); 183 break; 184 case JSVM_FLOAT32_ARRAY: 185 elementSize = sizeof(float); 186 break; 187 case JSVM_FLOAT64_ARRAY: 188 elementSize = sizeof(double); 189 break; 190 case JSVM_BIGINT64_ARRAY: 191 case JSVM_BIGUINT64_ARRAY: 192 elementSize = sizeof(int64_t); 193 break; 194 default: 195 // 默认创建JSVM_INT8_ARRAY类型 196 arrayType = JSVM_INT8_ARRAY; 197 elementSize = sizeof(int8_t); 198 break; 199 } 200 size_t length = DIFF_VALUE_THREE; 201 JSVM_Value arrayBuffer = nullptr; 202 JSVM_Value typedArray = nullptr; 203 void *data; 204 // 创建一个ArrayBuffer 205 OH_JSVM_CreateArraybuffer(env, length * elementSize, (void **)&data, &arrayBuffer); 206 // 根据给定类型创建TypedArray 207 JSVM_Status status = OH_JSVM_CreateTypedarray(env, arrayType, length, arrayBuffer, 0, &typedArray); 208 if (status != JSVM_OK) { 209 OH_LOG_ERROR(LOG_APP, "JSVM CreateTypedArray fail"); 210 } else { 211 OH_LOG_INFO(LOG_APP, "JSVM CreateTypedArray success"); 212 } 213 return typedArray; 214} 215// CreateTypedArray注册回调 216static JSVM_CallbackStruct param[] = { 217 {.data = nullptr, .callback = CreateTypedArray}, 218}; 219static JSVM_CallbackStruct *method = param; 220// CreateTypedArray方法别名,供JS调用 221static JSVM_PropertyDescriptor descriptor[] = { 222 {"createTypedArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 223}; 224// 样例测试js 225const char *srcCallNative = R"JS( 226const type = { 227 INT8_ARRAY: 0, 228 UINT8_ARRAY: 1, 229 UINT8_CLAMPED_ARRAY: 2, 230 INT16_ARRAY: 3, 231 UINT16_ARRAY: 4, 232 INT32_ARRAY: 5, 233 UINT32_ARRAY: 6, 234 FLOAT32_ARRAY: 7, 235 FLOAT64_ARRAY: 8, 236 BIGINT64_ARRAY: 9, 237 BIGUINT64_ARRAY: 10 238}; 239createTypedArray(type.INT8_ARRAY); 240createTypedArray(type.INT32_ARRAY); 241)JS"; 242``` 243 244### OH_JSVM_CreateDataview 245 246在现有的 ArrayBuffer 上创建一个 JavaScript DataView 对象,DataView 对象在底层数据缓冲区上提供类似数组的视图。 247 248cpp部分代码 249 250```cpp 251static int DIFF_VALUE_FOUR = 4; 252static int DIFF_VALUE_TWELVE = 12; 253// OH_JSVM_CreateDataview的样例方法 254static JSVM_Value CreateDataView(JSVM_Env env, JSVM_CallbackInfo info) 255{ 256 // 获取js侧传入的两个参数 257 size_t argc = 2; 258 JSVM_Value args[2] = {nullptr}; 259 JSVM_Value arrayBuffer = nullptr; 260 JSVM_Value result = nullptr; 261 // DataView的字节长度 262 size_t byteLength = DIFF_VALUE_TWELVE; 263 // 字节偏移量 264 size_t byteOffset = DIFF_VALUE_FOUR; 265 // 获取回调函数的参数信息 266 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 267 // 将参数转换为对象类型 268 OH_JSVM_CoerceToObject(env, args[0], &arrayBuffer); 269 // 创建一个数据视图对象,并指定字节长度和字节偏移量 270 JSVM_Status status = OH_JSVM_CreateDataview(env, byteLength, arrayBuffer, byteOffset, &result); 271 // 获取DataView的指针和长度信息 272 uint8_t *data = nullptr; 273 size_t length = 0; 274 // 为DataView赋值 275 for (size_t i = 0; i < length; i++) { 276 data[i] = static_cast<uint8_t>(i + 1); 277 } 278 int32_t infoType; 279 OH_JSVM_GetValueInt32(env, args[1], &infoType); 280 size_t returnLength; 281 JSVM_Value returnArrayBuffer = nullptr; 282 size_t returnOffset; 283 enum InfoType { BYTE_LENGTHE, ARRAY_BUFFERE, BYTE_OFFSET }; 284 // 获取dataview信息 285 OH_JSVM_GetDataviewInfo(env, result, &returnLength, (void **)&data, &returnArrayBuffer, &returnOffset); 286 JSVM_Value returnResult = nullptr; 287 switch (infoType) { 288 case BYTE_LENGTHE: 289 JSVM_Value len; 290 OH_JSVM_CreateInt32(env, returnLength, &len); 291 returnResult = len; 292 if (status != JSVM_OK) { 293 OH_LOG_ERROR(LOG_APP, "JSVM CreateDataView fail"); 294 } else { 295 OH_LOG_INFO(LOG_APP, "JSVM CreateDataView success, returnLength: %{public}d", returnLength); 296 } 297 break; 298 case ARRAY_BUFFERE: 299 bool isArraybuffer; 300 OH_JSVM_IsArraybuffer(env, returnArrayBuffer, &isArraybuffer); 301 JSVM_Value isArray; 302 OH_JSVM_GetBoolean(env, isArraybuffer, &isArray); 303 returnResult = isArray; 304 if (status != JSVM_OK) { 305 OH_LOG_ERROR(LOG_APP, "JSVM CreateDataView fail"); 306 } else { 307 OH_LOG_INFO(LOG_APP, "JSVM CreateDataView success, isArraybuffer: %{public}d", isArraybuffer); 308 } 309 break; 310 case BYTE_OFFSET: 311 JSVM_Value offset; 312 OH_JSVM_CreateInt32(env, returnOffset, &offset); 313 returnResult = offset; 314 if (status != JSVM_OK) { 315 OH_LOG_ERROR(LOG_APP, "JSVM CreateDataView fail"); 316 } else { 317 OH_LOG_INFO(LOG_APP, "JSVM CreateDataView success, returnOffset: %{public}d", returnOffset); 318 } 319 break; 320 default: 321 break; 322 } 323 return returnResult; 324} 325// CreateDataView注册回调 326static JSVM_CallbackStruct param[] = { 327 {.data = nullptr, .callback = CreateDataView}, 328}; 329static JSVM_CallbackStruct *method = param; 330// CreateDataView方法别名,供JS调用 331static JSVM_PropertyDescriptor descriptor[] = { 332 {"createDataView", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 333}; 334// 样例测试js 335const char *srcCallNative = R"JS( 336 let BYTE_LENGTH = 0; 337 createDataView(new ArrayBuffer(16), BYTE_LENGTH); 338 let IS_ARRAYBUFFER = 1; 339 createDataView(new ArrayBuffer(16), IS_ARRAYBUFFER); 340 let BYTE_OFFSET = 2; 341 createDataView(new ArrayBuffer(16), BYTE_OFFSET); 342)JS"; 343``` 344 345### OH_JSVM_GetArrayLength 346 347返回 Array 对象的长度。 348 349cpp 部分代码 350 351```cpp 352// hello.cpp 353#include "napi/native_api.h" 354#include "ark_runtime/jsvm.h" 355#include <hilog/log.h> 356// OH_JSVM_GetArrayLength的样例方法 357static JSVM_Value GetArrayLength(JSVM_Env env, JSVM_CallbackInfo info) 358{ 359 size_t argc = 1; 360 JSVM_Value args[1] = {nullptr}; 361 JSVM_Value result = nullptr; 362 uint32_t length; 363 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 364 // 检查参数是否为数组 365 bool isArray = false; 366 OH_JSVM_IsArray(env, args[0], &isArray); 367 if (!isArray) { 368 OH_LOG_INFO(LOG_APP, "JSVM Argument must be an array"); 369 return nullptr; 370 } 371 OH_JSVM_GetArrayLength(env, args[0], &length); 372 // 创建返回值 373 OH_JSVM_CreateInt32(env, length, &result); 374 OH_LOG_INFO(LOG_APP, "JSVM length: %{public}d", length); 375 return result; 376} 377// GetArrayLength注册回调 378static JSVM_CallbackStruct param[] = { 379 {.data = nullptr, .callback = GetArrayLength}, 380}; 381static JSVM_CallbackStruct *method = param; 382// GetArrayLength方法别名,供JS调用 383static JSVM_PropertyDescriptor descriptor[] = { 384 {"getArrayLength", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 385}; 386// 样例测试js 387const char *srcCallNative = R"JS( 388let data = [0, 1, 2, 3, 4, 5]; 389getArrayLength(data); 390)JS"; 391``` 392 393### OH_JSVM_GetTypedarrayInfo 394 395获取 TypedArray(类型化数组)对象的信息。 396 397cpp 部分代码 398 399```cpp 400// hello.cpp 401#include "napi/native_api.h" 402#include "ark_runtime/jsvm.h" 403#include <hilog/log.h> 404// OH_JSVM_GetTypedarrayInfo的样例方法 405static JSVM_Value GetTypedArrayInfo(JSVM_Env env, JSVM_CallbackInfo info) 406{ 407 // 获取并解析参数,第一个参数为需要获得的信息的TypedArray类型数据,第二个参数为需要获得的信息类型的枚举值 408 size_t argc = 2; 409 JSVM_Value args[2] = {nullptr}; 410 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 411 412 // 将第二个参数转为int32类型便于比较 413 int32_t infoTypeParam; 414 OH_JSVM_GetValueInt32(env, args[1], &infoTypeParam); 415 // 定义枚举类型与ArkTS侧枚举类型infoType顺序含义一致 416 enum InfoType { INFO_TYPE, INFO_LENGTH, INFO_ARRAY_BUFFER, INFO_BYTE_OFFSET }; 417 void *data; 418 JSVM_TypedarrayType type; 419 size_t byteOffset, length; 420 JSVM_Value arrayBuffer = nullptr; 421 // 调用接口OH_JSVM_GetTypedarrayInfo获得TypedArray类型数据的信息 422 JSVM_Status status = OH_JSVM_GetTypedarrayInfo(env, args[0], &type, &length, &data, &arrayBuffer, &byteOffset); 423 JSVM_Value result = nullptr; 424 // 根据属性名,返回TypedArray对应的属性值 425 switch (infoTypeParam) { 426 case INFO_TYPE: 427 // 如果传入的参数是int8类型的TypedArray数据,它的类型(type)为JSVM_INT8_ARRAY 428 JSVM_Value int8_type; 429 OH_JSVM_GetBoolean(env, type == JSVM_INT8_ARRAY, &int8_type); 430 result = int8_type; 431 if (status != JSVM_OK) { 432 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 433 } else { 434 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, JSVM_INT8_ARRAY: %{public}d", type == JSVM_INT8_ARRAY); 435 } 436 break; 437 case INFO_LENGTH: 438 // TypedArray中的元素数 439 JSVM_Value jsvmLength; 440 OH_JSVM_CreateInt32(env, length, &jsvmLength); 441 result = jsvmLength; 442 if (status != JSVM_OK) { 443 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 444 } else { 445 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, length: %{public}d", length); 446 } 447 break; 448 case INFO_BYTE_OFFSET: 449 // TypedArray数组的第一个元素所在的基础原生数组中的字节偏移量 450 JSVM_Value jsvmOffset; 451 OH_JSVM_CreateInt32(env, byteOffset, &jsvmOffset); 452 result = jsvmOffset; 453 if (status != JSVM_OK) { 454 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 455 } else { 456 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, byteOffset: %{public}d", byteOffset); 457 } 458 break; 459 case INFO_ARRAY_BUFFER: 460 // TypedArray下的ArrayBuffer 461 bool isArrayBuffer; 462 OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer); 463 JSVM_Value isArray; 464 OH_JSVM_GetBoolean(env, isArrayBuffer, &isArray); 465 result = isArray; 466 if (status != JSVM_OK) { 467 OH_LOG_ERROR(LOG_APP, "JSVM GetTypedArrayInfo fail"); 468 } else { 469 OH_LOG_INFO(LOG_APP, "JSVM GetTypedArrayInfo success, isArrayBuffer: %{public}d", isArrayBuffer); 470 } 471 break; 472 default: 473 break; 474 } 475 return result; 476} 477// GetTypedArrayInfo注册回调 478static JSVM_CallbackStruct param[] = { 479 {.data = nullptr, .callback = GetTypedArrayInfo}, 480}; 481static JSVM_CallbackStruct *method = param; 482// GetTypedArrayInfo方法别名,供JS调用 483static JSVM_PropertyDescriptor descriptor[] = { 484 {"getTypedArrayInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 485}; 486// 样例测试js 487const char *srcCallNative = R"JS( 488// is JSVM_INT8_ARRAY 489getTypedArrayInfo(new Int8Array(3), 0); 490// length 491getTypedArrayInfo(new Int8Array(5), 1); 492// is_arraybuffer 493getTypedArrayInfo(new Int8Array(5), 2); 494// byteoffset 495getTypedArrayInfo(new Int8Array(1), 3); 496)JS"; 497``` 498 499### OH_JSVM_GetDataviewInfo 500 501获取 Dataview 对象的信息。 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// OH_JSVM_GetDataviewInfo的样例方法 511static JSVM_Value GetDataViewInfo(JSVM_Env env, JSVM_CallbackInfo info) 512{ 513 // 获取并解析参数,第一个参数为需要获得的信息的DataView类型数据,第二个参数为需要获得的信息类型的枚举值 514 size_t argc = 2; 515 JSVM_Value args[2] = {nullptr}; 516 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 517 // 将第二个参数转为int32类型的数字 518 int32_t infoType; 519 OH_JSVM_GetValueInt32(env, args[1], &infoType); 520 size_t byteLength; 521 void *data; 522 JSVM_Value arrayBuffer = nullptr; 523 size_t byteOffset; 524 // 定义枚举类型与ArkTS侧枚举类型infoType顺序含义一致 525 enum infoTypeEnum { BYTE_LENGTHE, ARRAY_BUFFERE, BYTE_OFFSET }; 526 // 获取dataview信息 527 JSVM_Status status = OH_JSVM_GetDataviewInfo(env, args[0], &byteLength, &data, &arrayBuffer, &byteOffset); 528 JSVM_Value result = nullptr; 529 switch (infoType) { 530 case BYTE_LENGTHE: 531 // 返回查询DataView的长度 532 JSVM_Value len; 533 OH_JSVM_CreateInt32(env, byteLength, &len); 534 result = len; 535 if (status != JSVM_OK) { 536 OH_LOG_ERROR(LOG_APP, "JSVM GetDataViewInfo fail"); 537 } else { 538 OH_LOG_INFO(LOG_APP, "JSVM GetDataViewInfo success, byteLength: %{public}d", byteLength); 539 } 540 break; 541 case ARRAY_BUFFERE: 542 // 判断DataView的Info里的arraybuffer是否为arraybuffer 543 bool isArrayBuffer; 544 OH_JSVM_IsArraybuffer(env, arrayBuffer, &isArrayBuffer); 545 JSVM_Value isArray; 546 OH_JSVM_GetBoolean(env, isArrayBuffer, &isArray); 547 result = isArray; 548 if (status != JSVM_OK) { 549 OH_LOG_ERROR(LOG_APP, "JSVM GetDataViewInfo fail"); 550 } else { 551 OH_LOG_INFO(LOG_APP, "JSVM GetDataViewInfo success, isArrayBuffer: %{public}d", isArrayBuffer); 552 } 553 break; 554 case BYTE_OFFSET: 555 // 返回查询DataView的偏移量 556 JSVM_Value offset; 557 OH_JSVM_CreateInt32(env, byteOffset, &offset); 558 result = offset; 559 if (status != JSVM_OK) { 560 OH_LOG_ERROR(LOG_APP, "JSVM GetDataViewInfo fail"); 561 } else { 562 OH_LOG_INFO(LOG_APP, "JSVM GetDataViewInfo success, byteOffset: %{public}d", byteOffset); 563 } 564 break; 565 default: 566 break; 567 } 568 return result; 569} 570// GetDataViewInfo注册回调 571static JSVM_CallbackStruct param[] = { 572 {.data = nullptr, .callback = GetDataViewInfo}, 573}; 574static JSVM_CallbackStruct *method = param; 575// GetDataViewInfo方法别名,供JS调用 576static JSVM_PropertyDescriptor descriptor[] = { 577 {"getDataViewInfo", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 578}; 579// 样例测试js 580const char *srcCallNative = R"JS( 581// bytelength 582getDataViewInfo(new DataView(new Int8Array([2,5]).buffer), 0); 583// is arraybuffer 584let data = 'a'; 585let isarraybuffer = 1; 586getDataViewInfo(data, isarraybuffer); 587// is arraybuffer 588data = new DataView(new Int8Array([2,5,3]).buffer); 589isarraybuffer = 1; 590getDataViewInfo(data, isarraybuffer); 591// byte_offset 592data = new DataView(new Int8Array([2,5,3]).buffer); 593isarraybuffer = 2; 594getDataViewInfo(data, isarraybuffer); 595)JS"; 596``` 597 598### OH_JSVM_IsArray 599 600判断一个 JavaScript 对象是否为 Array 类型对象。 601 602cpp 部分代码 603 604```cpp 605// hello.cpp 606#include "napi/native_api.h" 607#include "ark_runtime/jsvm.h" 608#include <hilog/log.h> 609// OH_JSVM_IsArray的样例方法 610static JSVM_Value IsArray(JSVM_Env env, JSVM_CallbackInfo info) 611{ 612 size_t argc = 1; 613 JSVM_Value args[1] = {nullptr}; 614 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 615 bool result = false; 616 JSVM_Status status = OH_JSVM_IsArray(env, args[0], &result); 617 JSVM_Value returnValue = nullptr; 618 OH_JSVM_GetBoolean(env, result, &returnValue); 619 if (status != JSVM_OK) { 620 OH_LOG_ERROR(LOG_APP, "JSVM IsArray fail"); 621 } else { 622 OH_LOG_INFO(LOG_APP, "JSVM IsArray success, IsArray: %{public}d", result); 623 } 624 return returnValue; 625} 626// IsArray注册回调 627static JSVM_CallbackStruct param[] = { 628 {.data = nullptr, .callback = IsArray}, 629}; 630static JSVM_CallbackStruct *method = param; 631// IsArray方法别名,TS侧调用 632static JSVM_PropertyDescriptor descriptor[] = { 633 {"isArray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 634}; 635// 样例测试js 636const char *srcCallNative = R"JS( 637let data = [1, 2, 3, 4, 5]; 638isArray(data); 639)JS"; 640``` 641 642### OH_JSVM_SetElement 643 644在给定对象的指定索引处设置元素。 645 646cpp 部分代码 647 648```cpp 649// hello.cpp 650#include "napi/native_api.h" 651#include "ark_runtime/jsvm.h" 652#include <hilog/log.h> 653// OH_JSVM_SetElement的样例方法 654static int DIFF_VALUE_THREE = 3; 655static JSVM_Value SetElement(JSVM_Env env, JSVM_CallbackInfo info) { 656 size_t argc = DIFF_VALUE_THREE; 657 JSVM_Value args[3] = {nullptr}; 658 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 659 int32_t index = 0; 660 OH_JSVM_GetValueInt32(env, args[1], &index); 661 JSVM_Status status = OH_JSVM_SetElement(env, args[0], index, args[2]); 662 if (status != JSVM_OK) { 663 OH_LOG_ERROR(LOG_APP, "JSVM SetElement fail"); 664 } else { 665 OH_LOG_INFO(LOG_APP, "JSVM SetElement success"); 666 } 667 return args[0]; 668} 669// SetElement注册回调 670static JSVM_CallbackStruct param[] = { 671 {.data = nullptr, .callback = SetElement}, 672}; 673static JSVM_CallbackStruct *method = param; 674// SetElement方法别名,供JS调用 675static JSVM_PropertyDescriptor descriptor[] = { 676 {"setElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 677}; 678// 样例测试js 679const char *srcCallNative = R"JS( 680setElement(3); 681)JS"; 682``` 683 684### OH_JSVM_GetElement 685 686获取给定对象指定索引处的元素。 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// OH_JSVM_GetElement的样例方法 696static JSVM_Value GetElement(JSVM_Env env, JSVM_CallbackInfo info) { 697 // 获取js侧传入的两个参数 698 size_t argc = 2; 699 JSVM_Value args[2] = {nullptr}; 700 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 701 // 获取请求元素的索引值 702 uint32_t index; 703 OH_JSVM_GetValueUint32(env, args[1], &index); 704 // 获取请求索引位置的元素值并存储在result中 705 JSVM_Value result = nullptr; 706 JSVM_Status status = OH_JSVM_GetElement(env, args[0], index, &result); 707 if (status != JSVM_OK) { 708 OH_LOG_ERROR(LOG_APP, "JSVM GetElement fail"); 709 } else { 710 OH_LOG_INFO(LOG_APP, "JSVM GetElement success"); 711 } 712 return result; 713} 714// GetElement注册回调 715static JSVM_CallbackStruct param[] = { 716 {.data = nullptr, .callback = GetElement}, 717}; 718static JSVM_CallbackStruct *method = param; 719// GetElement方法别名,供JS调用 720static JSVM_PropertyDescriptor descriptor[] = { 721 {"getElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 722}; 723// 样例测试js 724const char *srcCallNative = R"JS( 725let arr = [10, 'hello', null, true]; 726getElement(arr, 3); 727)JS"; 728``` 729 730### OH_JSVM_HasElement 731 732若给定对象的指定索引处拥有属性,获取该元素。 733 734cpp 部分代码 735 736```cpp 737// hello.cpp 738#include "napi/native_api.h" 739#include "ark_runtime/jsvm.h" 740#include <hilog/log.h> 741// OH_JSVM_HasElement的样例方法 742static JSVM_Value HasElement(JSVM_Env env, JSVM_CallbackInfo info) 743{ 744 // 获取js侧传入的两个参数 745 size_t argc = 2; 746 JSVM_Value args[2] = {nullptr}; 747 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 748 // 获取要判断的元素的索引 749 uint32_t index; 750 OH_JSVM_GetValueUint32(env, args[1], &index); 751 // 判断指定索引位置的元素是否存在 752 bool hasElement = true; 753 JSVM_Status status = OH_JSVM_HasElement(env, args[0], index, &hasElement); 754 // 将boolean结果转换为JSVM_Value并返回 755 JSVM_Value result = nullptr; 756 OH_JSVM_GetBoolean(env, hasElement, &result); 757 if (status != JSVM_OK) { 758 OH_LOG_ERROR(LOG_APP, "JSVM hasElement fail"); 759 } else { 760 OH_LOG_INFO(LOG_APP, "JSVM hasElement: %{public}d", hasElement); 761 } 762 return result; 763} 764// HasElement注册回调 765static JSVM_CallbackStruct param[] = { 766 {.data = nullptr, .callback = HasElement}, 767}; 768static JSVM_CallbackStruct *method = param; 769// HasElement方法别名,供JS调用 770static JSVM_PropertyDescriptor descriptor[] = { 771 {"hasElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 772}; 773// 样例测试js 774const char *srcCallNative = R"JS( 775let arr = [10, 'hello', null, true]; 776hasElement(arr, 0); 777hasElement(arr, 4); 778)JS"; 779``` 780 781### OH_JSVM_DeleteElement 782 783尝试删除给定对象的指定索引处的元素。 784 785cpp部分代码 786 787```cpp 788// hello.cpp 789#include "napi/native_api.h" 790#include "ark_runtime/jsvm.h" 791#include <hilog/log.h> 792// OH_JSVM_DeleteElement的样例方法 793static JSVM_Value DeleteElement(JSVM_Env env, JSVM_CallbackInfo info) { 794 // 获取js侧传入的两个参数 795 size_t argc = 2; 796 JSVM_Value args[2] = {nullptr}; 797 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 798 // 获取要删除的元素的索引 799 uint32_t index; 800 OH_JSVM_GetValueUint32(env, args[1], &index); 801 // 尝试删除请求索引位置的元素 802 bool deleted = true; 803 JSVM_Status status = OH_JSVM_DeleteElement(env, args[0], index, &deleted); 804 // 将boolean结果转换为JSVM_Value并返回 805 JSVM_Value result = nullptr; 806 OH_JSVM_GetBoolean(env, deleted, &result); 807 if (status != JSVM_OK) { 808 OH_LOG_ERROR(LOG_APP, "JSVM DeleteElement fail"); 809 } else { 810 OH_LOG_INFO(LOG_APP, "JSVM DeleteElement: %{public}d", deleted); 811 } 812 return result; 813} 814// DeleteElement注册回调 815static JSVM_CallbackStruct param[] = { 816 {.data = nullptr, .callback = DeleteElement}, 817}; 818static JSVM_CallbackStruct *method = param; 819// DeleteElement方法别名,供JS调用 820static JSVM_PropertyDescriptor descriptor[] = { 821 {"deleteElement", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 822}; 823// 样例测试js 824const char *srcCallNative = R"JS( 825let arr = [10, 'hello', null, true]; 826deleteElement(arr, 0); 827)JS"; 828``` 829 830### OH_JSVM_IsDataview 831 832判断一个 JavaScript 对象是否为 Dataview类型对象。 833 834cpp 部分代码 835 836```cpp 837// hello.cpp 838#include "napi/native_api.h" 839#include "ark_runtime/jsvm.h" 840#include <hilog/log.h> 841// OH_JSVM_IsDataview的样例方法 842static JSVM_Value IsDataView(JSVM_Env env, JSVM_CallbackInfo info) { 843 size_t argc = 1; 844 JSVM_Value args[1] = {nullptr}; 845 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 846 // 调用OH_JSVM_IsDataview接口判断给定入参是否为DataView数据。 847 bool result = false; 848 JSVM_Status status = OH_JSVM_IsDataview(env, args[0], &result); 849 JSVM_Value isDateView = nullptr; 850 OH_JSVM_GetBoolean(env, result, &isDateView); 851 if (status != JSVM_OK) { 852 OH_LOG_ERROR(LOG_APP, "JSVM IsDataView fail"); 853 } else { 854 OH_LOG_INFO(LOG_APP, "JSVM IsDataView: %{public}d", result); 855 } 856 return isDateView; 857} 858// IsDataView注册回调 859static JSVM_CallbackStruct param[] = { 860 {.data = nullptr, .callback = IsDataView}, 861}; 862static JSVM_CallbackStruct *method = param; 863// IsDataView方法别名,TS侧调用 864static JSVM_PropertyDescriptor descriptor[] = { 865 {"isDataView", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 866}; 867// 样例测试js 868const char *srcCallNative = R"JS( 869let buffer = new ArrayBuffer(16); 870let dataView = new DataView(buffer); 871isDataView(dataView); 872)JS"; 873``` 874 875### OH_JSVM_IsTypedarray 876 877判断一个 JavaScript 对象是否为 Typedarray 类型对象。 878 879cpp 部分代码 880 881```cpp 882// hello.cpp 883#include "napi/native_api.h" 884#include "ark_runtime/jsvm.h" 885#include <hilog/log.h> 886// OH_JSVM_IsTypedarray的样例方法 887static JSVM_Value IsTypedarray(JSVM_Env env, JSVM_CallbackInfo info) { 888 size_t argc = 1; 889 JSVM_Value args[1] = {nullptr}; 890 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 891 bool result = false; 892 JSVM_Status status = OH_JSVM_IsTypedarray(env, args[0], &result); 893 JSVM_Value isTypedArray = nullptr; 894 OH_JSVM_GetBoolean(env, result, &isTypedArray); 895 if (status != JSVM_OK) { 896 OH_LOG_ERROR(LOG_APP, "JSVM IsTypedarray fail"); 897 } else { 898 OH_LOG_INFO(LOG_APP, "JSVM IsTypedarray: %{public}d", result); 899 } 900 return isTypedArray; 901} 902// IsTypedarray注册回调 903static JSVM_CallbackStruct param[] = { 904 {.data = nullptr, .callback = IsTypedarray}, 905}; 906static JSVM_CallbackStruct *method = param; 907// IsTypedarray方法别名,TS侧调用 908static JSVM_PropertyDescriptor descriptor[] = { 909 {"isTypedarray", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 910}; 911// 样例测试js 912const char *srcCallNative = R"JS( 913isTypedarray(new Uint16Array([1, 2, 3, 4])); 914)JS"; 915``` 916