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