1# 使用JSVM-API接口操作bigint类型值 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 11BigInt是JavaScript中用于表示任意精度整数的数据类型,能够处理比Number类型更大范围的整数值。JSVM-API提供的接口支持在JSVM模块中创建、获取和操作BigInt类型值。 12 13## 基本概念 14 15使用JSVM-API接口操作BigInt类型值需要理解以下基本概念: 16 17- **BigInt类型:** BigInt是JavaScript中的一种数据类型,用于表示任意精度的整数。与Number类型不同,BigInt类型可以精确表示非常大的整数,而不会丢失精度或溢出。 18- **BigInt创建:** 使用JSVM-API提供的接口,可以通过传递C的int64或uint64数据来创建对应的JavaScript BigInt。这使得在JSVM模块中可以方便地创建BigInt类型值。 19- **BigInt操作:** JSVM-API提供了多个接口用于操作BigInt类型值。通过这些接口,可以获取BigInt的数值,进行数值转换,以及执行常见的算术和位运算操作。 20 21## 接口说明 22 23| 接口 | 功能说明 | 24| ---------------------------- | ---------------------------------------- | 25| OH_JSVM_CreateBigintInt64 | 将C int64_t类型的值转换为JavaScript BigInt类型。| 26| OH_JSVM_CreateBigintUint64 | 将C uint64_t类型的值转换为JavaScript BigInt类型。| 27| OH_JSVM_CreateBigintWords | 将一组无符号64位字转换为单个BigInt值。| 28| OH_JSVM_GetValueBigintInt64 | 返回给定JavaScript BigInt的C int64_t基础类型等价值。 如果需要,它将截断该值,将lossless设置为false。 | 29| OH_JSVM_GetValueBigintUint64 | 返回给定JavaScript BigInt的C uint64_t基础类型等价值。 如果需要,它将截断该值,将lossless设置为false。 | 30| OH_JSVM_GetValueBigintWords | 将单个BigInt值转换为一个符号位、一个64位的小端数组和该数组的长度。 signBit和words参数可以都设置为NULL,这种情况下,只获取wordCount。| 31 32## 使用示例 33 34JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md)。本文仅展示接口对应的C++及ArkTS相关代码。 35 36### OH_JSVM_GetValueBigintWords 37 38获取给定JavaScript BigInt对象的底层数据,即BigInt数据的字词表示。 39 40cpp部分代码: 41 42```cpp 43// hello.cpp 44#include "napi/native_api.h" 45#include "ark_runtime/jsvm.h" 46#include <hilog/log.h> 47#include <fstream> 48 49// OH_JSVM_GetValueBigintWords的样例方法 50static JSVM_Value GetValueBigintWords(JSVM_Env env, JSVM_CallbackInfo info) { 51 size_t argc = 1; 52 JSVM_Value args[1] = {nullptr}; 53 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 54 int signBit = 0; 55 size_t wordCount = 0; 56 uint64_t* words{nullptr}; 57 // 调用OH_JSVM_GetValueBigintWords接口获取wordCount 58 JSVM_Status status = OH_JSVM_GetValueBigintWords(env, args[0], nullptr, &wordCount, nullptr); 59 OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords wordCount:%{public}d.", wordCount); 60 words = (uint64_t*)malloc(wordCount*sizeof(uint64_t)); 61 if (words == nullptr) { 62 OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords malloc failed."); 63 return nullptr; 64 } 65 // 调用OH_JSVM_GetValueBigintWords接口获取传入bigInt相关信息,如:signBit传入bigInt正负信息 66 status = OH_JSVM_GetValueBigintWords(env, args[0], &signBit, &wordCount, words); 67 free(words); 68 words = nullptr; 69 if (status != JSVM_OK) { 70 OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords fail, status:%{public}d.", status); 71 } else { 72 OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords signBit: %{public}d.", signBit); 73 } 74 // 将符号位转化为int类型传出去 75 JSVM_Value returnValue = nullptr; 76 OH_JSVM_CreateInt32(env, signBit, &returnValue); 77 return returnValue; 78} 79// GetValueBigintWords注册回调 80static JSVM_CallbackStruct param[] = { 81 {.data = nullptr, .callback = GetValueBigintWords}, 82}; 83static JSVM_CallbackStruct *method = param; 84// GetValueBigintWords方法别名,供JS调用 85static JSVM_PropertyDescriptor descriptor[] = { 86 {"getValueBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 87}; 88// 样例测试js 89const char* srcCallNative = R"JS(getValueBigintWords(BigInt(5555555555555555)))JS"; 90``` 91<!-- @[oh_jsvm_get_value_bigint_words](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutBigint/getvaluebigintwords/src/main/cpp/hello.cpp) --> 92 93预期的输出结果 94```ts 95OH_JSVM_GetValueBigintWords wordCount:1. 96OH_JSVM_GetValueBigintWords signBit: 0. 97``` 98 99### OH_JSVM_CreateBigintWords 100 101根据给定的Uint64_t数组创建一个JavaScript BigInt对象。 102 103cpp部分代码: 104 105```cpp 106// hello.cpp 107#include "napi/native_api.h" 108#include "ark_runtime/jsvm.h" 109#include <hilog/log.h> 110// OH_JSVM_CreateBigintWords的样例方法 111static int DIFF_VALUE_THREE = 3; 112static JSVM_Value CreateBigintWords(JSVM_Env env, JSVM_CallbackInfo info) 113{ 114 // 使用OH_JSVM_CreateBigintWords接口创建一个BigInt对象 115 int signBit = 0; 116 size_t wordCount = DIFF_VALUE_THREE; 117 uint64_t words[] = {12ULL, 34ULL, 56ULL}; 118 JSVM_Value returnValue = nullptr; 119 JSVM_Status status = OH_JSVM_CreateBigintWords(env, signBit, wordCount, words, &returnValue); 120 if (status != JSVM_OK) { 121 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintWords fail"); 122 } else { 123 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintWords success"); 124 } 125 return returnValue; 126} 127// CreateBigintWords注册回调 128static JSVM_CallbackStruct param[] = { 129 {.data = nullptr, .callback = CreateBigintWords}, 130}; 131static JSVM_CallbackStruct *method = param; 132// CreateBigintWords方法别名,供JS调用 133static JSVM_PropertyDescriptor descriptor[] = { 134 {"createBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 135}; 136// 样例测试js 137const char* srcCallNative = R"JS(createBigintWords())JS"; 138``` 139<!-- @[oh_jsvm_create_bigint_words](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutBigint/createbigintwords/src/main/cpp/hello.cpp) --> 140 141预期的输出结果 142```ts 143JSVM OH_JSVM_CreateBigintWords success 144``` 145 146### OH_JSVM_CreateBigintUint64 147 148根据给定的Uint64类型对象创建JavaScript BigInt对象。 149 150cpp部分代码: 151 152```cpp 153// hello.cpp 154#include "napi/native_api.h" 155#include "ark_runtime/jsvm.h" 156#include <hilog/log.h> 157// 声明uint64_t的变量value 158static uint64_t TEST_VALUE = 5555555555555555555; 159// OH_JSVM_CreateBigintUint64的样例方法 160static JSVM_Value CreateBigintUint64(JSVM_Env env, JSVM_CallbackInfo info) 161{ 162 // 将value转化为JSVM_Value类型返回 163 JSVM_Value returnValue = nullptr; 164 JSVM_Status status = OH_JSVM_CreateBigintUint64(env, TEST_VALUE, &returnValue); 165 if (status != JSVM_OK) { 166 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 fail"); 167 } else { 168 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 success"); 169 } 170 return returnValue; 171} 172// CreateBigintUint64注册回调 173static JSVM_CallbackStruct param[] = { 174 {.data = nullptr, .callback = CreateBigintUint64}, 175}; 176static JSVM_CallbackStruct *method = param; 177// CreateBigintUint64方法别名,供JS调用 178static JSVM_PropertyDescriptor descriptor[] = { 179 {"createBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 180}; 181// 样例测试js 182const char* srcCallNative = R"JS(createBigintUint64())JS"; 183``` 184<!-- @[oh_jsvm_create_bigint_uint64](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutBigint/createbigintuint64/src/main/cpp/hello.cpp) --> 185 186预期的输出结果 187```ts 188JSVM OH_JSVM_CreateBigintUint64 success 189 190``` 191 192### OH_JSVM_GetValueBigintUint64 193 194获取给定JavaScript BigInt的Uint64_t基础类型值。 195 196cpp部分代码: 197 198```cpp 199// hello.cpp 200#include "napi/native_api.h" 201#include "ark_runtime/jsvm.h" 202#include <hilog/log.h> 203// OH_JSVM_GetValueBigintUint64的样例方法 204static JSVM_Value GetValueBigintUint64(JSVM_Env env, JSVM_CallbackInfo info) 205{ 206 size_t argc = 1; 207 JSVM_Value args[1] = {nullptr}; 208 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 209 // 从参数值中获取BigInt的数值 210 uint64_t value = 0; 211 bool lossLess = false; 212 OH_JSVM_GetValueBigintUint64(env, args[0], &value, &lossLess); 213 // 判断从JS侧获取bigint是否为无损转换,如果不是抛出异常 214 if (!lossLess) { 215 OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted"); 216 return nullptr; 217 } else { 218 OH_LOG_INFO(LOG_APP, "JSVM GetValueBigintUint64 success"); 219 } 220 JSVM_Value returnValue = nullptr; 221 OH_JSVM_CreateBigintUint64(env, value, &returnValue); 222 return returnValue; 223} 224// GetValueBigintUint64注册回调 225static JSVM_CallbackStruct param[] = { 226 {.data = nullptr, .callback = GetValueBigintUint64}, 227}; 228static JSVM_CallbackStruct *method = param; 229// GetValueBigintUint64方法别名,供JS调用 230static JSVM_PropertyDescriptor descriptor[] = { 231 {"getValueBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 232}; 233// 样例测试js 234const char* srcCallNative = R"JS(getValueBigintUint64(BigInt(5555555555555555)))JS"; 235``` 236<!-- @[oh_jsvm_get_value_bigint_uint64](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutBigint/getvaluebigintuint64/src/main/cpp/hello.cpp) --> 237 238预期的输出结果 239```ts 240JSVM GetValueBigintUint64 success 241``` 242 243### OH_JSVM_CreateBigintInt64 244 245根据给定的Uint64类型对象创建JavaScript BigInt对象。 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// 声明int64_t的变量value 255static int64_t TEST_VALUE_DEMO = -5555555555555555555; 256// OH_JSVM_CreateBigintInt64的样例方法 257static JSVM_Value CreateBigintInt64(JSVM_Env env, JSVM_CallbackInfo info) 258{ 259 JSVM_Value returnValue = nullptr; 260 JSVM_Status status = OH_JSVM_CreateBigintInt64(env, TEST_VALUE_DEMO, &returnValue); 261 if (status != JSVM_OK) { 262 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 fail"); 263 } else { 264 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 success"); 265 } 266 return returnValue; 267} 268// CreateBigintInt64注册回调 269static JSVM_CallbackStruct param[] = { 270 {.data = nullptr, .callback = CreateBigintInt64}, 271}; 272static JSVM_CallbackStruct *method = param; 273// CreateBigintInt64方法别名,供JS调用 274static JSVM_PropertyDescriptor descriptor[] = { 275 {"createBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 276}; 277// 样例测试js 278const char* srcCallNative = R"JS(createBigintInt64())JS"; 279``` 280<!-- @[oh_jsvm_create_bigint_int64](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutBigint/createbigintint64/src/main/cpp/hello.cpp) --> 281 282预期的输出结果 283```ts 284JSVM OH_JSVM_CreateBigintInt64 success 285``` 286 287### OH_JSVM_GetValueBigintInt64 288 289用于从传入的参数中提取64位整数的BigInt数据,以供后续处理。 290 291cpp部分代码: 292 293```cpp 294// hello.cpp 295#include "napi/native_api.h" 296#include "ark_runtime/jsvm.h" 297#include <hilog/log.h> 298// OH_JSVM_GetValueBigintInt64的样例方法 299static JSVM_Value GetBigintInt64(JSVM_Env env, JSVM_CallbackInfo info) 300{ 301 size_t argc = 1; 302 JSVM_Value args[1] = {nullptr}; 303 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 304 // 从传入的参数中提取64位整数的BigInt数据 305 int64_t value = 0; 306 bool lossLess = false; 307 OH_JSVM_GetValueBigintInt64(env, args[0], &value, &lossLess); 308 // 判断从JS侧获取bigint是否为无损转换,如果不是抛出异常 309 if (!lossLess) { 310 OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted"); 311 return nullptr; 312 } else { 313 OH_LOG_INFO(LOG_APP, "JSVM GetBigintInt64 success"); 314 } 315 JSVM_Value returnValue = nullptr; 316 OH_JSVM_CreateBigintInt64(env, value, &returnValue); 317 return returnValue; 318} 319// GetBigintInt64注册回调 320static JSVM_CallbackStruct param[] = { 321 {.data = nullptr, .callback = GetBigintInt64}, 322}; 323static JSVM_CallbackStruct *method = param; 324// GetBigintInt64方法别名,供JS调用 325static JSVM_PropertyDescriptor descriptor[] = { 326 {"getBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 327}; 328// 样例测试js 329const char* srcCallNative = R"JS(getBigintInt64(BigInt(-5555555555555555)))JS"; 330``` 331<!-- @[oh_jsvm_get_value_bigint_int64](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/JSVMAPI/JsvmUsageGuide/JsvmAboutBigint/getvaluebigintint64/src/main/cpp/hello.cpp) --> 332 333预期的输出结果 334```ts 335JSVM GetValueBigintUint64 success 336``` 337