• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Working with Basic Data Types Using Node-API
2
3## Introduction
4
5The ArkTS Number type represents a double-precision 64-bit binary IEEE 754 value. Only integers in the range of -2^53+1 to 2^53-1 (inclusive) can be represented without loss of precision. Integers out of this range must be handled by Node-API interfaces for BigInt.
6
7## Basic Concepts
8
9Before using Node-API to create and obtain numbers, you need to understand the following concepts:
10
11- Number type<br>When using Node-API, you may need to convert values of number types between C and ArkTS. When converting the data, pay attention to the data range, signedness (signed or unsigned), and precision (single or double precision).
12- Error handling<br>You also need to use Node-API to capture and handle errors that may occur during the conversion. For example, when an integer is created, you may need to capture and handle memory allocation failures or other runtime errors.
13- Interaction between ArkTS and Node-API<br>During the development, you need to consider the interaction between ArkTS and Node-API, including how to pass the data of the number type and return the correct value.
14
15## Available APIs
16
17The following table lists the APIs provided by the Node-API module for converting number types between ArkTS and C/C++.
18| API| Description|
19| -------- | -------- |
20| napi_get_value_uint32 | Obtains a C uint32 value from an ArkTS number.|
21| napi_get_value_int32 | Obtains a C int32 value from an ArkTS number.|
22| napi_get_value_int64 | Obtains a C int64 value from an ArkTS number.|
23| napi_get_value_double | Obtains a C double value from an ArkTS number.|
24| napi_create_int32 | Creates an ArkTS number from a 32-bit signed integer.|
25| napi_create_uint32 | Creates an ArkTS number from a 32-bit unsigned integer.|
26| napi_create_int64 | Creates an ArkTS number from a 64-bit signed integer.|
27| napi_create_double | Creates an ArkTS number from a double-precision floating-point number.|
28
29## Example
30
31If you are just starting out with Node-API, see [Node-API Development Process](use-napi-process.md). The following demonstrates only the C++ and ArkTS code involved in the APIs for manipulating basic data types.
32
33### napi_get_value_uint32
34
35Use **napi_get_value_uint32** to obtain a 32-bit unsigned integer from an ArkTS number.
36
37CPP code:
38
39```cpp
40#include "napi/native_api.h"
41
42static napi_value GetValueUint32(napi_env env, napi_callback_info info)
43{
44    // Obtain the parameter of the Number type.
45    size_t argc = 1;
46    napi_value argv[1] = {nullptr};
47    // Parse the input parameters.
48    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
49
50    uint32_t number = 0;
51    // Obtain the 32-bit unsigned integer from the input parameter.
52    napi_status status = napi_get_value_uint32(env, argv[0], &number);
53    // If the input parameter is not a number, napi_number_expected will be thrown. Set the return value of the function to nullptr.
54    if (status == napi_number_expected) {
55        return nullptr;
56    }
57    napi_value result = nullptr;
58    // Create a 32-bit unsigned integer and output the integer.
59    napi_create_uint32(env, number, &result);
60    return result;
61}
62```
63
64API declaration:
65
66```ts
67// index.d.ts
68export const getValueUint32: <T>(data: T) => number | void;
69```
70
71ArkTS code:
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// If "sssss" (a non-number) is passed in, undefined will be returned.
81hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}s', data);
82// If 100 (a number within the uint32 value range) is passed in, the original number will be returned.
83hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', testNapi.getValueUint32<number>(100));
84```
85
86### napi_get_value_int32
87
88Use **napi_get_value_int32** to convert an ArkTS value to a C int32 value.
89
90CPP code:
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    // Parse the input parameter.
101    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
102    // Convert the parameter into a C int32 value.
103    napi_status status = napi_get_value_int32(env, args[0], &result32);
104    // If the input parameter is not a number, napi_number_expected will be thrown. Set the return value of the function to nullptr.
105    if (status == napi_number_expected) {
106        return nullptr;
107    }
108    // Call napi_create_int32 to convert the 32-bit signed integer into a napi_value and return it.
109    napi_value napiResult32 = nullptr;
110    napi_create_int32(env, result32, &napiResult32);
111    return napiResult32;
112}
113```
114
115API declaration:
116
117```ts
118// index.d.ts
119export const getValueInt32: (value: number | string) => number | void;
120```
121
122ArkTS code:
123
124```ts
125import hilog from '@ohos.hilog';
126import testNapi from 'libentry.so';
127
128// If 'ss' (a non-number) is passed in, undefined will be returned.
129hilog.info(0x0000, 'Node-API', 'get_value_int32_not_number %{public}s', testNapi.getValueInt32('ss'));
130// If 100 (a number within the int32 value range) is passed in, the original number will be returned.
131hilog.info(0x0000, 'Node-API', 'get_value_int32_number %{public}d', testNapi.getValueInt32(100));
132// If 68719476735 (which is 111111111111111111111111111111111111 in binary format and corresponds to the value -1 when interpreted as an int32 number) is passed in, -1 will be returned.
133hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(68719476735));
134// If the input number is greater than 2 <sup>31</sup>-1 and its binary format does not indicate a special number in int32 like 111111111111111111111111111111111111, the integer overflows. In this case, a number decoded from the last 32-bit binary code will be returned.
135hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(687194767355));
136// If NaN (Not-a-Number), +Infinity (positive infinity), or -Infinity (negative infinity) is passed in, 0 will be returned.
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
144Use **napi_get_value_int64** to convert an ArkTS value to a C int64 value.
145
146CPP code:
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    // Parse the parameter passed in.
157    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
158    // Convert the parameter into a C int64 value.
159    napi_status status = napi_get_value_int64(env, args[0], &result64);
160    // If the input parameter is not a number, return napi_number_expected.
161    if (status == napi_number_expected) {
162        return nullptr;
163    }
164    // Call napi_create_int64 to convert the int64 value to a napi_value and return it.
165    napi_value napiResult64 = nullptr;
166    napi_create_int64(env, result64, &napiResult64);
167    return napiResult64;
168}
169```
170
171API declaration:
172
173```ts
174// index.d.ts
175export const getValueInt64: (value: number | string) => number | void;
176```
177
178ArkTS code:
179
180```ts
181import hilog from '@ohos.hilog';
182import testNapi from 'libentry.so';
183
184// If a number within the int64 value range is passed in, the original number will be returned.
185hilog.info(0x0000, 'Node-API', 'get_value_int64_number %{public}d', testNapi.getValueInt64(80));
186// If 'sAs' (a non-number) is passed in, undefined will be returned.
187hilog.info(0x0000, 'Node-API', 'get_value_int64_not_number %{public}s', testNapi.getValueInt64('sAs'));
188// If a number out of the int64 value range is passed in, it will cause integer overflow and loss of precision. The number returned is not equal to the number passed in.
189hilog.info(0x0000, 'Node-API', 'get_value_int64_number_oversize %{public}d', testNapi.getValueInt64(9223372036854775809));
190// If NaN (Not-a-Number), +Infinity (positive infinity), or -Infinity (negative infinity) is passed in, 0 will be returned.
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
198Use **napi_get_value_double** to convert an ArkTS value to a C double value.
199
200CPP code:
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    // If a non-number is passed in, napi_number_expected will be thrown.
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
222API declaration:
223
224```ts
225// index.d.ts
226export const getDouble: (value: number | string) => number | void;
227```
228
229ArkTS code:
230
231```ts
232import hilog from '@ohos.hilog';
233import testNapi from 'libentry.so';
234// If a number is passed in, the number will be returned.
235hilog.info(0x0000, 'Node-API', 'get_value_double_number %{public}d', testNapi.getDouble(80.885));
236// If a non-number is passed in, undefined will be returned.
237hilog.info(0x0000, 'Node-API', 'get_value_double_not_number %{public}s', testNapi.getDouble('sAs'));
238```
239
240### napi_create_int32
241
242Use **napi_create_int32** to create an ArkTS number from a 32-bit signed integer.
243
244CPP code:
245
246```cpp
247#include "napi/native_api.h"
248static constexpr int INT_NUM_NEG_26 = -26;   // Integer -26
249
250static napi_value CreateInt32(napi_env env, napi_callback_info info)
251{
252    // int32_t represents a 32-bit signed integer, ranging from -2^31 to 2^31 - 1, that is, -2147483648 to 2147483647.
253    //
254    int32_t value = INT_NUM_NEG_26;
255    // Create an ArkTS Int32 number.
256    napi_value result = nullptr;
257    napi_status status = napi_create_int32(env, value, &result);
258    if (status != napi_ok) {
259        // Error handling.
260        napi_throw_error(env, nullptr, "Failed to create int32 value");
261    }
262    return result;
263}
264```
265
266API declaration:
267
268```ts
269// index.d.ts
270export const createInt32: () => number;
271```
272
273ArkTS code:
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
284Use **napi_create_uint32** to create an ArkTS number from a 32-bit unsigned integer.
285
286CPP code:
287
288```cpp
289#include "napi/native_api.h"
290static constexpr int INT_NUM_26 = 26;   // Integer 26
291
292static napi_value CreateUInt32(napi_env env, napi_callback_info info)
293{
294    // If the uint32_t type is used to represent -26, overflow occurs. Modulo operation is performed on the result to convert the binary complement of the negative number to a positive number. That is, 4294967270 will be returned.
295    // uint32_t represents a 32-bit unsigned integer, ranging from 0 to 2^32 - 1, that is, 0 to 4294967295.
296    //
297    uint32_t value = INT_NUM_26;
298    // Create an ArkTS Uint32 number.
299    napi_value result = nullptr;
300    napi_status status = napi_create_uint32(env, value, &result);
301    if (status != napi_ok) {
302        // Error handling.
303        napi_throw_error(env, nullptr, "Failed to create uint32 value");
304    }
305    return result;
306}
307```
308
309API declaration:
310
311```ts
312// index.d.ts
313export const createUInt32: () => number;
314```
315
316ArkTS code:
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
327Use **napi_create_int64** to create an ArkTS number from a 64-bit signed integer.
328
329CPP code:
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    // Create an ArkTS number using the given value. Only integers in the range from -2^53 + 1 to 2^53 - 1 (inclusive) can be accurately represented.
339    // If the value to be represented exceeds 2^53, use napi_create_bigint64.
340    napi_value result = nullptr;
341    napi_status status = napi_create_int64(env, value, &result);
342    if (status != napi_ok) {
343        // Error handling.
344        napi_throw_error(env, nullptr, "Failed to create int64 value");
345    }
346    return result;
347}
348```
349
350API declaration:
351
352```ts
353// index.d.ts
354export const createInt64: () => number;
355```
356
357ArkTS code:
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
368Use **napi_create_double** to create an ArkTS number from a double-precision floating-point number.
369
370CPP code:
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    // Create an ArkTS double number.
379    napi_value result = nullptr;
380    napi_status status = napi_create_double(env, value, &result);
381    if (status != napi_ok) {
382        // Error handling.
383        napi_throw_error(env, nullptr, "Failed to create double value");
384    }
385    return result;
386}
387```
388
389API declaration:
390
391```ts
392// index.d.ts
393export const createDouble: () => number;
394```
395
396ArkTS code:
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
405To print logs in the native CPP, add the following information to the **CMakeLists.txt** file and add the header file by using **#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