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