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" 248 249static napi_value CreateInt32(napi_env env, napi_callback_info info) 250{ 251 // int32_t是有符号的32位整数类型,表示带有符号的整数,它的范围是从-2^31到2^31 - 1,也就是-2147483648到2147483647 252 // 要表示的整数值 253 int32_t value = -26; 254 // 创建ArkTS中的int32数字 255 napi_value result = nullptr; 256 napi_status status = napi_create_int32(env, value, &result); 257 if (status != napi_ok) { 258 // 处理错误 259 napi_throw_error(env, nullptr, "Failed to create int32 value"); 260 } 261 return result; 262} 263``` 264 265接口声明 266 267```ts 268// index.d.ts 269export const createInt32: () => number; 270``` 271 272ArkTS侧示例代码 273 274```ts 275import hilog from '@ohos.hilog' 276import testNapi from 'libentry.so' 277 278hilog.info(0x0000, 'testTag','Test Node-API napi_create_int32:' + testNapi.createInt32()); 279``` 280 281### napi_create_uint32 282 283用于创建一个ArkTS数字(uint32类型)的值。 284 285cpp部分代码 286 287```cpp 288#include "napi/native_api.h" 289 290static napi_value CreateUInt32(napi_env env, napi_callback_info info) 291{ 292 // 如果使用 uint32_t类型来定义-26,会发生溢出,溢出时会对结果进行模运算,将负数的二进制补码转换为相应的正数。-26输出4294967270 293 // uint32_t是无符号的32位整数类型,只能表示非负整数。它的范围是从0到2 ^32 - 1,即0到4294967295 294 // 要表示的整数值 295 uint32_t value = 26; 296 // 创建ArkTS中的uint32数字 297 napi_value result = nullptr; 298 napi_status status = napi_create_uint32(env, value, &result); 299 if (status != napi_ok) { 300 // 处理错误 301 napi_throw_error(env, nullptr, "Failed to create uint32 value"); 302 } 303 return result; 304} 305``` 306 307接口声明 308 309```ts 310// index.d.ts 311export const createUInt32: () => number; 312``` 313 314ArkTS侧示例代码 315 316```ts 317import hilog from '@ohos.hilog' 318import testNapi from 'libentry.so' 319 320 hilog.info(0x0000, 'testTag','Test Node-API napi_create_uint32: ' + testNapi.createUInt32()); 321``` 322 323### napi_create_int64 324 325用于创建一个ArkTS数字(int64类型)的值。 326 327cpp部分代码 328 329```cpp 330#include "napi/native_api.h" 331 332static napi_value CreateInt64(napi_env env, napi_callback_info info) 333{ 334 // int64是有符号的64位整数类型,可以表示范围从-2^63到2^63 - 1的整数,即 -9223372036854775808到9223372036854775807 335 // 要表示的整数值 336 int64_t value = 2147483648; 337 // 创建ArkTS中的int64数字 338 napi_value result = nullptr; 339 napi_status status = napi_create_int64(env, value, &result); 340 if (status != napi_ok) { 341 // 处理错误 342 napi_throw_error(env, nullptr, "Failed to create int64 value"); 343 } 344 return result; 345} 346``` 347 348接口声明 349 350```ts 351// index.d.ts 352export const createInt64: () => number; 353``` 354 355ArkTS侧示例代码 356 357```ts 358import hilog from '@ohos.hilog' 359import testNapi from 'libentry.so' 360 361hilog.info(0x0000, 'testTag','Test Node-API napi_create_int64: ' + testNapi.createInt64()); 362``` 363 364### napi_create_double 365 366用于创建一个ArkTS数字(double类型)的值。 367 368cpp部分代码 369 370```cpp 371#include "napi/native_api.h" 372 373static napi_value CreateDouble(napi_env env, napi_callback_info info) 374{ 375 double value = 1.234; 376 // 创建ArkTS中的double数字 377 napi_value result = nullptr; 378 napi_status status = napi_create_double(env, value, &result); 379 if (status != napi_ok) { 380 // 处理错误 381 napi_throw_error(env, nullptr, "Failed to create double value"); 382 } 383 return result; 384} 385``` 386 387接口声明 388 389```ts 390// index.d.ts 391export const createDouble: () => number; 392``` 393 394ArkTS侧示例代码 395 396```ts 397import hilog from '@ohos.hilog' 398import testNapi from 'libentry.so' 399 400hilog.info(0x0000, 'testTag','Test Node-API napi_create_double: ' + testNapi.createDouble()); 401``` 402 403以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"): 404 405```text 406// CMakeLists.txt 407add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 408add_definitions( "-DLOG_TAG=\"testTag\"" ) 409target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 410``` 411