1# 使用JSVM-API接口创建基本数据类型
2
3## 简介
4
5在JavaScript中,整数类型是一种基本数据类型,用于表示没有小数部分的数值。double类型用于表示有小数的数值。JavaScript的数值存储方式会导致在某些情况下无法准确表示非常大或非常小的数值,在这种情况下,需要使用BigInt对应的JSVM-API接口来处理更大范围的整数。
6
7## 基本概念
8
9当使用JSVM-API接口进行数值类型的创建和获取时,有一些基本概念需要了解:
10
11- **数值类型** 在使用JSVM-API接口时,可能需要从JSVM模块数值类型转换为JavaScript数值类型值,或者从JavaScript数据类型值转换为JSVM模块数值类型。在进行数据类型转换时,需要注意数据范围是否匹配,以及有无符号整数和双精度数值等区别。
12- **错误处理** 在使用这些接口时,需要对可能发生的错误进行适当处理。比如,在创建整数值时可能发生内存分配错误或其他运行时错误,需要使用JSVM-API提供的错误处理机制来捕获并处理这些错误。
13- **JavaScript交互** 在开发过程中,需要考虑如何将创建的数值类型值与JavaScript环境进行交互,包括传递参数、返回值等。
14
15## 接口说明
16
17| 接口                  | 功能说明                                        |
18| --------------------- | -----------------------------------------------|
19| OH_JSVM_GetValueUint32 | 获取给定JavaScript number的Uint32基础类型值。   |
20| OH_JSVM_GetValueInt32  | 获取给定JavaScript number的Int32基础类型值。    |
21| OH_JSVM_GetValueInt64  | 获取给定JavaScript number的Int64基础类型值。    |
22| OH_JSVM_GetValueDouble | 获取给定JavaScript number的Double基础类型值。   |
23| OH_JSVM_CreateInt32     | 根据Int32_t类型对象创建JavaScript number对象。 |
24| OH_JSVM_CreateUint32    | 根据Uint32_t类型对象创建JavaScript number对象。|
25| OH_JSVM_CreateInt64     | 根据Int64_t类型对象创建JavaScript number对象。 |
26| OH_JSVM_CreateDouble    | 根据Double类型对象创建JavaScript number对象。  |
27
28## 使用示例
29
30JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++相关代码进行展示。
31
32### OH_JSVM_GetValueUint32
33
34将JavaScript value转为JSVM模块中的uint32类型数据。
35
36cpp部分代码
37
38```cpp
39// hello.cpp
40#include "napi/native_api.h"
41#include "ark_runtime/jsvm.h"
42#include <hilog/log.h>
43
44// OH_JSVM_GetValueUint32的样例方法
45static JSVM_Value GetValueUint32(JSVM_Env env, JSVM_CallbackInfo info)
46{
47    // 获取传入的数字类型参数
48    size_t argc = 1;
49    JSVM_Value argv[1] = {nullptr};
50    // 解析传入的参数
51    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
52    uint32_t number = 0;
53    // 获取传入参数的值中的无符号32位整数
54    JSVM_Status status = OH_JSVM_GetValueUint32(env, argv[0], &number);
55    if (status != JSVM_OK) {
56        OH_LOG_ERROR(LOG_APP, "JSVM GetValueUint32 fail");
57    } else {
58        OH_LOG_INFO(LOG_APP, "JSVM GetValueUint32 success: %{public}u", number);
59    }
60    return argv[0];
61}
62
63// GetValueUint32注册回调
64static JSVM_CallbackStruct param[] = {
65    {.data = nullptr, .callback = GetValueUint32},
66};
67static JSVM_CallbackStruct *method = param;
68
69// GetValueUint32方法别名,供JS调用
70static JSVM_PropertyDescriptor descriptor[] = {
71    {"getValueUint32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
72};
73
74// 样例测试js
75const char* srcCallNative = R"JS(getValueUint32(123))JS";
76```
77
78预期的输出结果
79
80```
81JSVM GetValueUint32 success: 123
82```
83
84### OH_JSVM_GetValueInt32
85
86将JavaScript value转为JSVM模块中的int32类型数据。
87
88cpp部分代码
89
90```cpp
91// hello.cpp
92#include "napi/native_api.h"
93#include "ark_runtime/jsvm.h"
94#include <hilog/log.h>
95
96// OH_JSVM_GetValueInt32的样例方法
97static JSVM_Value GetValueInt32(JSVM_Env env, JSVM_CallbackInfo info)
98{
99    size_t argc = 1;
100    JSVM_Value args[1] = {nullptr};
101    int32_t result32 = 0;
102    // 解析传递的参数
103    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
104    // 将前端传过来的参数转为JSVM模块的int32类型
105    JSVM_Status status = OH_JSVM_GetValueInt32(env, args[0], &result32);
106    if (status != JSVM_OK) {
107        return nullptr;
108    }
109    if (status != JSVM_OK) {
110        OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt32 fail");
111    } else {
112        OH_LOG_INFO(LOG_APP, "JSVM GetValueInt32 success: %{public}d", result32);
113    }
114    return args[0];
115}
116
117// GetValueInt32注册回调
118static JSVM_CallbackStruct param[] = {
119    {.data = nullptr, .callback = GetValueInt32},
120};
121static JSVM_CallbackStruct *method = param;
122// GetValueInt32方法别名,供JS调用
123static JSVM_PropertyDescriptor descriptor[] = {
124    {"getValueInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
125};
126
127// 样例测试js
128const char* srcCallNative = R"JS(getValueInt32(-123))JS";
129```
130
131预期的输出结果
132
133```
134JSVM GetValueInt32 success: -123
135```
136
137### OH_JSVM_GetValueInt64
138
139将JavaScript value转为JSVM模块中的int64类型数据。
140
141cpp部分代码
142
143```cpp
144// hello.cpp
145#include "napi/native_api.h"
146#include "ark_runtime/jsvm.h"
147#include <hilog/log.h>
148
149// OH_JSVM_GetValueInt64的样例方法
150static JSVM_Value GetValueInt64(JSVM_Env env, JSVM_CallbackInfo info)
151{
152    size_t argc = 1;
153    JSVM_Value args[1] = {nullptr};
154    int64_t result64 = 0;
155    // 解析传递的值
156    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
157    // 将前端传过来的参数分别转为JSVM模块的int64类型
158    JSVM_Status status = OH_JSVM_GetValueInt64(env, args[0], &result64);
159    if (status != JSVM_OK) {
160        OH_LOG_ERROR(LOG_APP, "JSVM GetValueInt64 fail");
161    } else {
162        OH_LOG_INFO(LOG_APP, "JSVM GetValueInt64 success: %{public}d", result64);
163    }
164    return args[0];
165}
166
167// GetValueInt64注册回调
168static JSVM_CallbackStruct param[] = {
169    {.data = nullptr, .callback = GetValueInt64},
170};
171static JSVM_CallbackStruct *method = param;
172// GetValueInt64方法别名,供JS调用
173static JSVM_PropertyDescriptor descriptor[] = {
174    {"getValueInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
175};
176
177// 样例测试js
178const char* srcCallNative = R"JS(getValueInt64(-123))JS";
179```
180
181预期的输出结果
182
183```
184JSVM GetValueInt64 success: -123
185```
186
187### OH_JSVM_GetValueDouble
188
189将JavaScript value转为JSVM模块中的double类型数据。
190
191cpp部分代码
192
193```cpp
194// hello.cpp
195#include "napi/native_api.h"
196#include "ark_runtime/jsvm.h"
197#include <hilog/log.h>
198
199// OH_JSVM_GetValueDouble的样例方法
200static JSVM_Value GetDouble(JSVM_Env env, JSVM_CallbackInfo info)
201{
202    size_t argc = 1;
203    JSVM_Value args[1] = {nullptr};
204    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
205    double value;
206    JSVM_Status status = OH_JSVM_GetValueDouble(env, args[0], &value);
207    if (status != JSVM_OK) {
208        OH_LOG_ERROR(LOG_APP, "JSVM GetDouble fail");
209    } else {
210        OH_LOG_INFO(LOG_APP, "JSVM GetDouble success: %{public}f", value);
211    }
212    return args[0];
213}
214
215// GetDouble注册回调
216static JSVM_CallbackStruct param[] = {
217    {.data = nullptr, .callback = GetDouble},
218};
219static JSVM_CallbackStruct *method = param;
220// GetDouble方法别名,供JS调用
221static JSVM_PropertyDescriptor descriptor[] = {
222    {"getDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
223};
224
225// 样例测试js
226const char* srcCallNative = R"JS(getDouble(-110.0456))JS";
227```
228
229预期的输出结果
230
231```
232JSVM GetDouble success: -110.045600
233```
234
235### OH_JSVM_CreateInt32
236
237用于创建一个JavaScript number(int32类型)的值。
238
239cpp部分代码
240
241```cpp
242// hello.cpp
243#include "napi/native_api.h"
244#include "ark_runtime/jsvm.h"
245#include <hilog/log.h>
246
247// OH_JSVM_CreateInt32的样例方法
248static JSVM_Value CreateInt32(JSVM_Env env, JSVM_CallbackInfo info)
249{
250    int32_t value = -20;
251    // 创建JavaScript中的int32数字
252    JSVM_Value result = nullptr;
253    JSVM_Status status = OH_JSVM_CreateInt32(env, value, &result);
254    if (status != JSVM_OK) {
255        OH_LOG_ERROR(LOG_APP, "JSVM CreateInt32 fail");
256    } else {
257        int32_t number = 0;
258        OH_JSVM_GetValueInt32(env, result, &number);
259        OH_LOG_INFO(LOG_APP, "JSVM CreateInt32 success: %{public}d", number);
260    }
261    return result;
262}
263
264// CreateInt32注册回调
265static JSVM_CallbackStruct param[] = {
266    {.data = nullptr, .callback = CreateInt32},
267};
268static JSVM_CallbackStruct *method = param;
269// CreateInt32方法别名,供JS调用
270static JSVM_PropertyDescriptor descriptor[] = {
271    {"createInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
272};
273
274// 样例测试js
275const char* srcCallNative = R"JS(createInt32())JS";
276```
277
278预期的输出结果
279
280```
281JSVM CreateInt32 success: -20
282```
283
284### OH_JSVM_CreateUint32
285
286用于创建一个JavaScript number(uint32类型)的值。
287
288cpp部分代码
289
290```cpp
291// hello.cpp
292#include "napi/native_api.h"
293#include "ark_runtime/jsvm.h"
294#include <hilog/log.h>
295
296// OH_JSVM_CreateUint32的样例方法
297static JSVM_Value CreateUInt32(JSVM_Env env, JSVM_CallbackInfo info)
298{
299    // 如果使用
300    // uint32_t类型来定义-26,会发生溢出,溢出时会对结果进行模运算,将负数的二进制补码转换为相应的正数。-26输出4294967270
301    // uint32_t是无符号的32位整数类型,只能表示非负整数。它的范围是从0到2 ^32 - 1,即0到4294967295
302    // 要表示的整数值
303    uint32_t value = 26;
304    // 创建JavaScript中的uint32数字
305    JSVM_Value result = nullptr;
306    JSVM_Status status = OH_JSVM_CreateUint32(env, value, &result);
307    if (status != JSVM_OK) {
308        OH_LOG_ERROR(LOG_APP, "JSVM CreateUInt32 fail");
309    } else {
310        uint32_t number = 0;
311        OH_JSVM_GetValueUint32(env, result, &number);
312        OH_LOG_INFO(LOG_APP, "JSVM CreateUInt32 success: %{public}u", number);
313    }
314    return result;
315}
316
317// CreateUInt32注册回调
318static JSVM_CallbackStruct param[] = {
319    {.data = nullptr, .callback = CreateUInt32},
320};
321static JSVM_CallbackStruct *method = param;
322// CreateUInt32方法别名,供JS调用
323static JSVM_PropertyDescriptor descriptor[] = {
324    {"createUInt32", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
325};
326
327// 样例测试js
328const char* srcCallNative = R"JS(createUInt32())JS";
329```
330
331预期的输出结果
332
333```
334JSVM CreateUInt32 success: 26
335```
336
337### OH_JSVM_CreateInt64
338
339用于创建一个JavaScript number(int64类型)的值。
340
341cpp部分代码
342
343```cpp
344// hello.cpp
345#include "napi/native_api.h"
346#include "ark_runtime/jsvm.h"
347#include <hilog/log.h>
348
349// OH_JSVM_CreateInt64的样例方法
350static JSVM_Value CreateInt64(JSVM_Env env, JSVM_CallbackInfo info)
351{
352    // int64是有符号的64位整数类型,可以表示范围从-2^63到2^63 - 1的整数,即 -9223372036854775808到9223372036854775807
353    // 要表示的整数值
354    int64_t value = 2147483648;
355    // 创建JavaScript中的int64数字
356    JSVM_Value result = nullptr;
357    JSVM_Status status = OH_JSVM_CreateInt64(env, value, &result);
358    if (status != JSVM_OK) {
359        OH_LOG_ERROR(LOG_APP, "JSVM CreateInt64 fail");
360    } else {
361        int64_t number = 0;
362        OH_JSVM_GetValueInt64(env, result, &number);
363        OH_LOG_INFO(LOG_APP, "JSVM CreateInt64 success: %{public}ld", number);
364    }
365    return result;
366}
367
368// CreateInt64注册回调
369static JSVM_CallbackStruct param[] = {
370    {.data = nullptr, .callback = CreateInt64},
371};
372static JSVM_CallbackStruct *method = param;
373// CreateInt64方法别名,供JS调用
374static JSVM_PropertyDescriptor descriptor[] = {
375    {"createInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
376};
377
378// 样例测试js
379const char* srcCallNative = R"JS(createInt64())JS";
380```
381
382预期的输出结果
383
384```
385JSVM CreateInt64 success: 2147483648
386```
387
388### OH_JSVM_CreateDouble
389
390用于创建一个JavaScript number(double类型)的值。
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// CreateDouble注册回调
400
401// OH_JSVM_CreateDouble的样例方法
402static JSVM_Value CreateDouble(JSVM_Env env, JSVM_CallbackInfo info)
403{
404    double value = 1.234;
405    // 创建JavaScript中的double数字
406    JSVM_Value result = nullptr;
407    JSVM_Status status = OH_JSVM_CreateDouble(env, value, &result);
408    if (status != JSVM_OK) {
409        OH_LOG_ERROR(LOG_APP, "JSVM CreateDouble fail");
410    } else {
411        double number = 0;
412        OH_JSVM_GetValueDouble(env, result, &number);
413        OH_LOG_INFO(LOG_APP, "JSVM CreateDouble success: %{public}f", number);
414    }
415    return result;
416}
417
418static JSVM_CallbackStruct param[] = {
419    {.data = nullptr, .callback = CreateDouble},
420};
421static JSVM_CallbackStruct *method = param;
422// CreateDouble方法别名,供JS调用
423static JSVM_PropertyDescriptor descriptor[] = {
424    {"createDouble", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
425};
426
427// 样例测试js
428const char* srcCallNative = R"JS(createDouble())JS";
429```
430
431预期的输出结果
432
433```
434JSVM CreateDouble success: 1.234000
435```
436