• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用Node-API接口创建基本数据类型
2
3## 简介
4
5ArkTS的Number类型是一个双精度64位二进制格式IEEE 754值。只有在-2^53+1到2^53-1范围内(闭区间)的整数才能在不丢失精度的情况下被表示,在超过该取值范围的情况下,需要使用BigInt对应的NPI接口来处理更大范围的整数。
6
7## 基本概念
8
9当使用Node-API接口进行数值类型的创建和获取时,有一些基本概念需要了解:
10
11- **数值类型** 在使用Node-API接口时,可能需要从Node-API模块数值类型转换为ArkTS数值类型值,或者从ArkTS数据类型值转换为Node-API模块数值类型。在进行数据类型转换时,需要注意数据范围是否匹配,以及有无符号整数和双精度数值等区别。
12- **错误处理** 在使用这些接口时,需要对可能发生的错误进行适当处理。比如,在创建整数值时可能发生内存分配错误或其他运行时错误,需要使用Node-API提供的错误处理机制来捕获并处理这些错误。
13- **ArkTS交互** 在开发过程中,需要考虑如何将创建的数值类型值与ArkTS环境进行交互,包括传递参数、返回值等。
14
15## 场景和功能介绍
16
17以下Node-API函数通常在开发ArkTS的Node-API模块时使用,以便处理数值类型值,帮助开发人员在Node-API模块中和JavaScrip数值进行交互:
18| 接口 | 描述 |
19| -------- | -------- |
20| napi_get_value_uint32 | 将ArkTS环境中number类型数据转为Node-API模块中的uint32类型数据。 |
21| napi_get_value_int32 | 将ArkTS环境中获取的number类型数据转为Node-API模块中的int32类型数据。 |
22| napi_get_value_int64 | 将ArkTS环境中获取的number类型数据转为Node-API模块中的int64类型数据。 |
23| napi_get_value_double | 将ArkTS环境中获取的number类型数据转为Node-API模块中的double类型数据。 |
24| napi_create_int32 | 将Node-API模块中的int32_t类型转换为ArkTS环境中number类型。 |
25| napi_create_uint32 | 将Node-API模块中的uint32_t类型转换为ArkTS环境中number类型。 |
26| napi_create_int64 | 将Node-API模块中的int64_t类型转换为ArkTS环境中number类型。 |
27| napi_create_double | 将Node-API模块中的double类型转换为ArkTS环境中number类型。 |
28
29## 使用示例
30
31Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
32
33### napi_get_value_uint32
34
35用于从ArkTS环境中获取32位无符号整数值。
36
37cpp部分代码
38
39```cpp
40#include "napi/native_api.h"
41
42static napi_value GetValueUint32(napi_env env, napi_callback_info info)
43{
44    // 获取传入的数字类型参数
45    size_t argc = 1;
46    napi_value argv[1] = {nullptr};
47    // 解析传入的参数
48    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
49
50    uint32_t number = 0;
51    // 获取传入参数的值中的无符号32位整数
52    napi_status status = napi_get_value_uint32(env, argv[0], &number);
53    // 如果传递的参数不是数字,将会返回napi_number_expected,设置函数返回nullptr
54    if (status == napi_number_expected) {
55        return nullptr;
56    }
57    napi_value result = nullptr;
58    // 创建传入参数无符号32位整数,并传出
59    napi_create_uint32(env, number, &result);
60    return result;
61}
62```
63
64接口声明
65
66```ts
67// index.d.ts
68export const getValueUint32: <T>(data: T) => number | void;
69```
70
71ArkTS侧示例代码
72
73```ts
74import hilog from '@ohos.hilog'
75import testNapi from 'libentry.so'
76
77let value = testNapi.getValueUint32<number>(111111111111);
78let data = testNapi.getValueUint32<string>("sssss");
79hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', value);
80// 传入非数字"sssss"时函数返回undefined
81hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}s', data);
82// 传入uint32范围内的数字100时函数返回原数字
83hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', testNapi.getValueUint32<number>(100));
84```
85
86### napi_get_value_int32
87
88将ArkTS value转为Node-API模块中的int32类型数据。
89
90cpp部分代码
91
92```cpp
93#include "napi/native_api.h"
94
95static napi_value GetValueInt32(napi_env env, napi_callback_info info)
96{
97    size_t argc = 1;
98    napi_value args[1] = {nullptr};
99    int32_t result32 = 0;
100    // 解析传递的参数
101    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
102    // 将前端传过来的参数转为Node-API模块的int32类型
103    napi_status status = napi_get_value_int32(env, args[0], &result32);
104    // 如果传递的参数不是数字napi_get_value_int32接口将会返回napi_number_expected,设置函数返回nullptr
105    if (status == napi_number_expected) {
106        return nullptr;
107    }
108    // 调用napi_create_int32接口将int32类型的数据转为napi_value返回
109    napi_value napiResult32 = nullptr;
110    napi_create_int32(env, result32, &napiResult32);
111    return napiResult32;
112}
113```
114
115接口声明
116
117```ts
118// index.d.ts
119export const getValueInt32: (value: number | string) => number | void;
120```
121
122ArkTS侧示例代码
123
124```ts
125import hilog from '@ohos.hilog'
126import testNapi from 'libentry.so'
127
128// 传入非数字“ss”时函数返回undefined
129hilog.info(0x0000, 'Node-API', 'get_value_int32_not_number %{public}s', testNapi.getValueInt32('ss'));
130// 传入int32范围内的数字100时函数返回原数字
131hilog.info(0x0000, 'Node-API', 'get_value_int32_number %{public}d', testNapi.getValueInt32(100));
132// 传入68719476735,此数字的二进制为111111111111111111111111111111111111,在int32类型中此二进制代表数字-1
133hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(68719476735));
134// 大于2的31次-1的数字且不是二进制为111111111111111111111111111111111111这样的在int32中有特殊含义的数字也会溢出,导致数值发生改变,返回值按后32位二进制编码解码
135hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(687194767355));
136// 传入NAN(not a number)、+Infinity(正无穷)或-Infinity(负无穷),会返回数字0
137hilog.info(0x0000, 'Node-API', 'get_value_int32_number_NAN %{public}d', testNapi.getValueInt32(NaN));
138hilog.info(0x0000, 'Node-API', 'get_value_int32_number_+Infinity %{public}d', testNapi.getValueInt32(+Infinity));
139hilog.info(0x0000, 'Node-API', 'get_value_int32_number_-Infinity %{public}d', testNapi.getValueInt32(-Infinity));
140```
141
142### napi_get_value_int64
143
144将ArkTS value转为Node-API模块中的int64类型数据。
145
146cpp部分代码
147
148```cpp
149#include "napi/native_api.h"
150
151static napi_value GetValueInt64(napi_env env, napi_callback_info info)
152{
153    size_t argc = 1;
154    napi_value args[1] = {nullptr};
155    int64_t result64 = 0;
156    // 解析传递的值
157    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
158    // 将前端传过来的参数转为Node-API模块的int64类型
159    napi_status status = napi_get_value_int64(env, args[0], &result64);
160    // 如果传递的参数不是数字, 返回napi_number_expected.
161    if (status == napi_number_expected) {
162        return nullptr;
163    }
164    // 调用napi_create_int64接口将int64类型的数据转为napi_value返回前端
165    napi_value napiResult64 = nullptr;
166    napi_create_int64(env, result64, &napiResult64);
167    return napiResult64;
168}
169```
170
171接口声明
172
173```ts
174// index.d.ts
175export const getValueInt64: (value: number | string) => number | void;
176```
177
178ArkTS侧示例代码
179
180```ts
181import hilog from '@ohos.hilog'
182import testNapi from 'libentry.so'
183
184// 输入不超过int64表示范围的数字,会返回该数字
185hilog.info(0x0000, 'Node-API', 'get_value_int64_number %{public}d', testNapi.getValueInt64(80));
186// 传入非数字“ss”,获得函数返回的值应为undefined
187hilog.info(0x0000, 'Node-API', 'get_value_int64_not_number %{public}s', testNapi.getValueInt64('sAs'));
188// 输入超过int64表示范围的数字会溢出,失去精度,导致输入数字与返回数字不相等
189hilog.info(0x0000, 'Node-API', 'get_value_int64_number_oversize %{public}d', testNapi.getValueInt64(9223372036854775809));
190// 传入NAN(not a number)、+Infinity(正无穷)或-Infinity(负无穷)接口返回数字0
191hilog.info(0x0000, 'Node-API', 'get_value_int64_number_NAN %{public}d', testNapi.getValueInt64(NaN));
192hilog.info(0x0000, 'Node-API', 'get_value_int64_number_+Infinity %{public}d', testNapi.getValueInt64(+Infinity));
193hilog.info(0x0000, 'Node-API', 'get_value_int64_number_-Infinity %{public}d', testNapi.getValueInt64(-Infinity));
194```
195
196### napi_get_value_double
197
198将ArkTS value转为Node-API模块中的double类型数据。
199
200cpp部分代码
201
202```cpp
203#include "napi/native_api.h"
204
205static napi_value GetDouble(napi_env env, napi_callback_info info)
206{
207    size_t argc = 1;
208    napi_value args[1] = {nullptr};
209    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
210    double value = 0;
211    napi_status status = napi_get_value_double(env, args[0], &value);
212    // 传入非数字接口返回napi_number_expected
213    if (status == napi_number_expected) {
214        return nullptr;
215    }
216    napi_value result = nullptr;
217    napi_create_double(env, value, &result);
218    return result;
219}
220```
221
222接口声明
223
224```ts
225// index.d.ts
226export const getDouble: (value: number | string) => number | void;
227```
228
229ArkTS侧示例代码
230
231```ts
232import hilog from '@ohos.hilog'
233import testNapi from 'libentry.so'
234// 输入数字,返回该数字
235hilog.info(0x0000, 'Node-API', 'get_value_double_number %{public}d', testNapi.getDouble(80.885));
236// 传入非数字,获得函数返回的值应为undefined
237hilog.info(0x0000, 'Node-API', 'get_value_double_not_number %{public}s', testNapi.getDouble('sAs'));
238```
239
240### napi_create_int32
241
242用于创建一个ArkTS数字(int32类型)的值。
243
244cpp部分代码
245
246```cpp
247#include "napi/native_api.h"
248static constexpr int INT_NUM_NEG_26 = -26;   // int类型数值-26
249
250static napi_value CreateInt32(napi_env env, napi_callback_info info)
251{
252    // int32_t是有符号的32位整数类型,表示带有符号的整数,它的范围是从-2^31到2^31 - 1,也就是-2147483648到2147483647
253    // 要表示的整数值
254    int32_t value = INT_NUM_NEG_26;
255    // 创建ArkTS中的int32数字
256    napi_value result = nullptr;
257    napi_status status = napi_create_int32(env, value, &result);
258    if (status != napi_ok) {
259        // 处理错误
260        napi_throw_error(env, nullptr, "Failed to create int32 value");
261    }
262    return result;
263}
264```
265
266接口声明
267
268```ts
269// index.d.ts
270export const createInt32: () => number;
271```
272
273ArkTS侧示例代码
274
275```ts
276import hilog from '@ohos.hilog'
277import testNapi from 'libentry.so'
278
279hilog.info(0x0000, 'testTag','Test Node-API napi_create_int32:' + testNapi.createInt32());
280```
281
282### napi_create_uint32
283
284用于创建一个ArkTS数字(uint32类型)的值。
285
286cpp部分代码
287
288```cpp
289#include "napi/native_api.h"
290static constexpr int INT_NUM_26 = 26;   // int类型数值26
291
292static napi_value CreateUInt32(napi_env env, napi_callback_info info)
293{
294    // 如果使用 uint32_t类型来定义-26,会发生溢出,溢出时会对结果进行模运算,将负数的二进制补码转换为相应的正数。-26输出4294967270
295    // uint32_t是无符号的32位整数类型,只能表示非负整数。它的范围是从0到2 ^32 - 1,即0到4294967295
296    // 要表示的整数值
297    uint32_t value = INT_NUM_26;
298    // 创建ArkTS中的uint32数字
299    napi_value result = nullptr;
300    napi_status status = napi_create_uint32(env, value, &result);
301    if (status != napi_ok) {
302        // 处理错误
303        napi_throw_error(env, nullptr, "Failed to create uint32 value");
304    }
305    return result;
306}
307```
308
309接口声明
310
311```ts
312// index.d.ts
313export const createUInt32: () => number;
314```
315
316ArkTS侧示例代码
317
318```ts
319import hilog from '@ohos.hilog'
320import testNapi from 'libentry.so'
321
322hilog.info(0x0000, 'testTag','Test Node-API napi_create_uint32: ' + testNapi.createUInt32());
323```
324
325### napi_create_int64
326
327用于创建一个ArkTS数字(int64类型)的值。
328
329cpp部分代码
330
331```cpp
332#include "napi/native_api.h"
333
334static napi_value CreateInt64(napi_env env, napi_callback_info info)
335{
336    // 要表示的整数值
337    int64_t value = 2147483648;
338    // 使用给定数值创建一个ArkTS number,仅能准确表示范围从-2^53 + 1到2^53 - 1(闭区间)的整数
339    // 如果想表示的数值超过了2^53,请使用napi_create_bigint64接口
340    napi_value result = nullptr;
341    napi_status status = napi_create_int64(env, value, &result);
342    if (status != napi_ok) {
343        // 处理错误
344        napi_throw_error(env, nullptr, "Failed to create int64 value");
345    }
346    return result;
347}
348```
349
350接口声明
351
352```ts
353// index.d.ts
354export const createInt64: () => number;
355```
356
357ArkTS侧示例代码
358
359```ts
360import hilog from '@ohos.hilog'
361import testNapi from 'libentry.so'
362
363hilog.info(0x0000, 'testTag','Test Node-API napi_create_int64: ' + testNapi.createInt64());
364```
365
366### napi_create_double
367
368用于创建一个ArkTS数字(double类型)的值。
369
370cpp部分代码
371
372```cpp
373#include "napi/native_api.h"
374
375static napi_value CreateDouble(napi_env env, napi_callback_info info)
376{
377    double value = 1.234;
378    // 创建ArkTS中的double数字
379    napi_value result = nullptr;
380    napi_status status = napi_create_double(env, value, &result);
381    if (status != napi_ok) {
382        // 处理错误
383        napi_throw_error(env, nullptr, "Failed to create double value");
384    }
385    return result;
386}
387```
388
389接口声明
390
391```ts
392// index.d.ts
393export const createDouble: () => number;
394```
395
396ArkTS侧示例代码
397
398```ts
399import hilog from '@ohos.hilog'
400import testNapi from 'libentry.so'
401
402hilog.info(0x0000, 'testTag','Test Node-API napi_create_double: ' + testNapi.createDouble());
403```
404
405以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
406
407```text
408// CMakeLists.txt
409add_definitions( "-DLOG_DOMAIN=0xd0d0" )
410add_definitions( "-DLOG_TAG=\"testTag\"" )
411target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
412```
413