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