# 使用Node-API接å£åˆ›å»ºåŸºæœ¬æ•°æ®ç±»åž‹ ## 简介 ArkTSçš„Number类型是一个åŒç²¾åº¦64ä½äºŒè¿›åˆ¶æ ¼å¼IEEE 754å€¼ã€‚åªæœ‰åœ¨-2^53+1到2^53-1范围内(é—区间)的整数æ‰èƒ½åœ¨ä¸ä¸¢å¤±ç²¾åº¦çš„æƒ…况下被表示,在超过该å–值范围的情况下,需è¦ä½¿ç”¨BigInt对应的NPIæŽ¥å£æ¥å¤„ç†æ›´å¤§èŒƒå›´çš„æ•´æ•°ã€‚ ## 基本概念 当使用Node-API接å£è¿›è¡Œæ•°å€¼ç±»åž‹çš„åˆ›å»ºå’ŒèŽ·å–æ—¶ï¼Œæœ‰ä¸€äº›åŸºæœ¬æ¦‚念需è¦äº†è§£ï¼š - **数值类型** 在使用Node-APIæŽ¥å£æ—¶ï¼Œå¯èƒ½éœ€è¦ä»ŽNode-APIæ¨¡å—æ•°å€¼ç±»åž‹è½¬æ¢ä¸ºArkTS数值类型值,或者从ArkTSæ•°æ®ç±»åž‹å€¼è½¬æ¢ä¸ºNode-APIæ¨¡å—æ•°å€¼ç±»åž‹ã€‚在进行数æ®ç±»åž‹è½¬æ¢æ—¶ï¼Œéœ€è¦æ³¨æ„æ•°æ®èŒƒå›´æ˜¯å¦åŒ¹é…ï¼Œä»¥åŠæœ‰æ— ç¬¦å·æ•´æ•°å’ŒåŒç²¾åº¦æ•°å€¼ç‰åŒºåˆ«ã€‚ - **错误处ç†** åœ¨ä½¿ç”¨è¿™äº›æŽ¥å£æ—¶ï¼Œéœ€è¦å¯¹å¯èƒ½å‘生的错误进行适当处ç†ã€‚比如,在创建整数值时å¯èƒ½å‘生内å˜åˆ†é…错误或其他è¿è¡Œæ—¶é”™è¯¯ï¼Œéœ€è¦ä½¿ç”¨Node-APIæä¾›çš„é”™è¯¯å¤„ç†æœºåˆ¶æ¥æ•获并处ç†è¿™äº›é”™è¯¯ã€‚ - **ArkTS交互** 在开å‘过程ä¸ï¼Œéœ€è¦è€ƒè™‘如何将创建的数值类型值与ArkTSçŽ¯å¢ƒè¿›è¡Œäº¤äº’ï¼ŒåŒ…æ‹¬ä¼ é€’å‚æ•°ã€è¿”回值ç‰ã€‚ ## åœºæ™¯å’ŒåŠŸèƒ½ä»‹ç» ä»¥ä¸‹Node-API函数通常在开å‘ArkTSçš„Node-APIæ¨¡å—æ—¶ä½¿ç”¨ï¼Œä»¥ä¾¿å¤„ç†æ•°å€¼ç±»åž‹å€¼ï¼Œå¸®åЩ开å‘人员在Node-API模å—ä¸å’ŒJavaScrip数值进行交互: | æŽ¥å£ | æè¿° | | -------- | -------- | | napi_get_value_uint32 | å°†ArkTS环境ä¸number类型数æ®è½¬ä¸ºNode-API模å—ä¸çš„uint32类型数æ®ã€‚ | | napi_get_value_int32 | å°†ArkTS环境ä¸èŽ·å–çš„number类型数æ®è½¬ä¸ºNode-API模å—ä¸çš„int32类型数æ®ã€‚ | | napi_get_value_int64 | å°†ArkTS环境ä¸èŽ·å–çš„number类型数æ®è½¬ä¸ºNode-API模å—ä¸çš„int64类型数æ®ã€‚ | | napi_get_value_double | å°†ArkTS环境ä¸èŽ·å–çš„number类型数æ®è½¬ä¸ºNode-API模å—ä¸çš„double类型数æ®ã€‚ | | napi_create_int32 | å°†Node-API模å—ä¸çš„int32_t类型转æ¢ä¸ºArkTS环境ä¸number类型。 | | napi_create_uint32 | å°†Node-API模å—ä¸çš„uint32_t类型转æ¢ä¸ºArkTS环境ä¸number类型。 | | napi_create_int64 | å°†Node-API模å—ä¸çš„int64_t类型转æ¢ä¸ºArkTS环境ä¸number类型。 | | napi_create_double | å°†Node-API模å—ä¸çš„double类型转æ¢ä¸ºArkTS环境ä¸number类型。 | ## 使用示例 Node-API接å£å¼€å‘æµç¨‹å‚考[使用Node-API实现跨è¯è¨€äº¤äº’开呿µç¨‹](use-napi-process.md),本文仅对接å£å¯¹åº”C++åŠArkTS相关代ç 进行展示。 ### napi_get_value_uint32 用于从ArkTS环境ä¸èŽ·å–32使— ç¬¦å·æ•´æ•°å€¼ã€‚ cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value GetValueUint32(napi_env env, napi_callback_info info) { // 获å–ä¼ å…¥çš„æ•°å—ç±»åž‹å‚æ•° size_t argc = 1; napi_value argv[1] = {nullptr}; // è§£æžä¼ å…¥çš„å‚æ•° napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); uint32_t number = 0; // 获å–ä¼ å…¥å‚æ•°çš„值ä¸çš„æ— 符å·32使•´æ•° napi_status status = napi_get_value_uint32(env, argv[0], &number); // å¦‚æžœä¼ é€’çš„å‚æ•°ä¸æ˜¯æ•°å—,将会返回napi_number_expected,设置函数返回nullptr if (status == napi_number_expected) { return nullptr; } napi_value result = nullptr; // åˆ›å»ºä¼ å…¥å‚æ•°æ— 符å·32使•´æ•°ï¼Œå¹¶ä¼ 出 napi_create_uint32(env, number, &result); return result; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const getValueUint32: <T>(data: T) => number | void; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' let value = testNapi.getValueUint32<number>(111111111111); let data = testNapi.getValueUint32<string>("sssss"); hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', value); // ä¼ å…¥éžæ•°å—"sssss"时函数返回undefined hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}s', data); // ä¼ å…¥uint32范围内的数å—100æ—¶å‡½æ•°è¿”å›žåŽŸæ•°å— hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', testNapi.getValueUint32<number>(100)); ``` ### napi_get_value_int32 å°†ArkTS value转为Node-API模å—ä¸çš„int32类型数æ®ã€‚ cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value GetValueInt32(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1] = {nullptr}; int32_t result32 = 0; // è§£æžä¼ é€’çš„å‚æ•° napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); // å°†å‰ç«¯ä¼ 过æ¥çš„傿•°è½¬ä¸ºNode-API模å—çš„int32类型 napi_status status = napi_get_value_int32(env, args[0], &result32); // å¦‚æžœä¼ é€’çš„å‚æ•°ä¸æ˜¯æ•°å—napi_get_value_int32接å£å°†ä¼šè¿”回napi_number_expected,设置函数返回nullptr if (status == napi_number_expected) { return nullptr; } // 调用napi_create_int32接å£å°†int32类型的数æ®è½¬ä¸ºnapi_value返回 napi_value napiResult32 = nullptr; napi_create_int32(env, result32, &napiResult32); return napiResult32; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const getValueInt32: (value: number | string) => number | void; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' // ä¼ å…¥éžæ•°å—“ssâ€æ—¶å‡½æ•°è¿”回undefined hilog.info(0x0000, 'Node-API', 'get_value_int32_not_number %{public}s', testNapi.getValueInt32('ss')); // ä¼ å…¥int32范围内的数å—100æ—¶å‡½æ•°è¿”å›žåŽŸæ•°å— hilog.info(0x0000, 'Node-API', 'get_value_int32_number %{public}d', testNapi.getValueInt32(100)); // ä¼ å…¥68719476735ï¼Œæ¤æ•°å—的二进制为111111111111111111111111111111111111,在int32ç±»åž‹ä¸æ¤äºŒè¿›åˆ¶ä»£è¡¨æ•°å—-1 hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(68719476735)); // 大于2çš„31次-1的数å—䏔䏿˜¯äºŒè¿›åˆ¶ä¸º111111111111111111111111111111111111è¿™æ ·çš„åœ¨int32䏿œ‰ç‰¹æ®Šå«ä¹‰çš„æ•°å—也会溢出,导致数值å‘生改å˜ï¼Œè¿”回值按åŽ32ä½äºŒè¿›åˆ¶ç¼–ç è§£ç hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(687194767355)); // ä¼ å…¥NAN(not a number)ã€+Infinityï¼ˆæ£æ— 穷)或-Infinityï¼ˆè´Ÿæ— ç©·ï¼‰ï¼Œä¼šè¿”å›žæ•°å—0 hilog.info(0x0000, 'Node-API', 'get_value_int32_number_NAN %{public}d', testNapi.getValueInt32(NaN)); hilog.info(0x0000, 'Node-API', 'get_value_int32_number_+Infinity %{public}d', testNapi.getValueInt32(+Infinity)); hilog.info(0x0000, 'Node-API', 'get_value_int32_number_-Infinity %{public}d', testNapi.getValueInt32(-Infinity)); ``` ### napi_get_value_int64 å°†ArkTS value转为Node-API模å—ä¸çš„int64类型数æ®ã€‚ cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value GetValueInt64(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1] = {nullptr}; int64_t result64 = 0; // è§£æžä¼ 递的值 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); // å°†å‰ç«¯ä¼ 过æ¥çš„傿•°è½¬ä¸ºNode-API模å—çš„int64类型 napi_status status = napi_get_value_int64(env, args[0], &result64); // å¦‚æžœä¼ é€’çš„å‚æ•°ä¸æ˜¯æ•°å—, 返回napi_number_expected. if (status == napi_number_expected) { return nullptr; } // 调用napi_create_int64接å£å°†int64类型的数æ®è½¬ä¸ºnapi_value返回å‰ç«¯ napi_value napiResult64 = nullptr; napi_create_int64(env, result64, &napiResult64); return napiResult64; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const getValueInt64: (value: number | string) => number | void; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' // 输入ä¸è¶…过int64表示范围的数å—ï¼Œä¼šè¿”å›žè¯¥æ•°å— hilog.info(0x0000, 'Node-API', 'get_value_int64_number %{public}d', testNapi.getValueInt64(80)); // ä¼ å…¥éžæ•°å—“ssâ€ï¼ŒèŽ·å¾—å‡½æ•°è¿”å›žçš„å€¼åº”ä¸ºundefined hilog.info(0x0000, 'Node-API', 'get_value_int64_not_number %{public}s', testNapi.getValueInt64('sAs')); // 输入超过int64表示范围的数å—会溢出,失去精度,导致输入数å—与返回数å—ä¸ç›¸ç‰ hilog.info(0x0000, 'Node-API', 'get_value_int64_number_oversize %{public}d', testNapi.getValueInt64(9223372036854775809)); // ä¼ å…¥NAN(not a number)ã€+Infinityï¼ˆæ£æ— 穷)或-Infinityï¼ˆè´Ÿæ— ç©·ï¼‰æŽ¥å£è¿”回数å—0 hilog.info(0x0000, 'Node-API', 'get_value_int64_number_NAN %{public}d', testNapi.getValueInt64(NaN)); hilog.info(0x0000, 'Node-API', 'get_value_int64_number_+Infinity %{public}d', testNapi.getValueInt64(+Infinity)); hilog.info(0x0000, 'Node-API', 'get_value_int64_number_-Infinity %{public}d', testNapi.getValueInt64(-Infinity)); ``` ### napi_get_value_double å°†ArkTS value转为Node-API模å—ä¸çš„double类型数æ®ã€‚ cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value GetDouble(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1] = {nullptr}; napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); double value = 0; napi_status status = napi_get_value_double(env, args[0], &value); // ä¼ å…¥éžæ•°å—接å£è¿”回napi_number_expected if (status == napi_number_expected) { return nullptr; } napi_value result = nullptr; napi_create_double(env, value, &result); return result; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const getDouble: (value: number | string) => number | void; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' // 输入数å—ï¼Œè¿”å›žè¯¥æ•°å— hilog.info(0x0000, 'Node-API', 'get_value_double_number %{public}d', testNapi.getDouble(80.885)); // ä¼ å…¥éžæ•°å—,获得函数返回的值应为undefined hilog.info(0x0000, 'Node-API', 'get_value_double_not_number %{public}s', testNapi.getDouble('sAs')); ``` ### napi_create_int32 用于创建一个ArkTSæ•°å—(int32类型)的值。 cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value CreateInt32(napi_env env, napi_callback_info info) { // int32_t是有符å·çš„32使•´æ•°ç±»åž‹ï¼Œè¡¨ç¤ºå¸¦æœ‰ç¬¦å·çš„æ•´æ•°ï¼Œå®ƒçš„范围是从-2^31到2^31 - 1,也就是-2147483648到2147483647 // è¦è¡¨ç¤ºçš„æ•´æ•°å€¼ int32_t value = -26; // 创建ArkTSä¸çš„int32æ•°å— napi_value result = nullptr; napi_status status = napi_create_int32(env, value, &result); if (status != napi_ok) { // 处ç†é”™è¯¯ napi_throw_error(env, nullptr, "Failed to create int32 value"); } return result; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const createInt32: () => number; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' hilog.info(0x0000, 'testTag','Test Node-API napi_create_int32:' + testNapi.createInt32()); ``` ### napi_create_uint32 用于创建一个ArkTSæ•°å—(uint32类型)的值。 cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value CreateUInt32(napi_env env, napi_callback_info info) { // 如果使用 uint32_t类型æ¥å®šä¹‰-26,会å‘生溢出,溢出时会对结果进行模è¿ç®—,将负数的二进制补ç 转æ¢ä¸ºç›¸åº”çš„æ£æ•°ã€‚-26输出4294967270 // uint32_tæ˜¯æ— ç¬¦å·çš„32使•´æ•°ç±»åž‹ï¼Œåªèƒ½è¡¨ç¤ºéžè´Ÿæ•´æ•°ã€‚它的范围是从0到2 ^32 - 1,å³0到4294967295 // è¦è¡¨ç¤ºçš„æ•´æ•°å€¼ uint32_t value = 26; // 创建ArkTSä¸çš„uint32æ•°å— napi_value result = nullptr; napi_status status = napi_create_uint32(env, value, &result); if (status != napi_ok) { // 处ç†é”™è¯¯ napi_throw_error(env, nullptr, "Failed to create uint32 value"); } return result; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const createUInt32: () => number; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' hilog.info(0x0000, 'testTag','Test Node-API napi_create_uint32: ' + testNapi.createUInt32()); ``` ### napi_create_int64 用于创建一个ArkTSæ•°å—(int64类型)的值。 cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value CreateInt64(napi_env env, napi_callback_info info) { // int64是有符å·çš„64使•´æ•°ç±»åž‹ï¼Œå¯ä»¥è¡¨ç¤ºèŒƒå›´ä»Ž-2^63到2^63 - 1çš„æ•´æ•°ï¼Œå³ -9223372036854775808到9223372036854775807 // è¦è¡¨ç¤ºçš„æ•´æ•°å€¼ int64_t value = 2147483648; // 创建ArkTSä¸çš„int64æ•°å— napi_value result = nullptr; napi_status status = napi_create_int64(env, value, &result); if (status != napi_ok) { // 处ç†é”™è¯¯ napi_throw_error(env, nullptr, "Failed to create int64 value"); } return result; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const createInt64: () => number; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' hilog.info(0x0000, 'testTag','Test Node-API napi_create_int64: ' + testNapi.createInt64()); ``` ### napi_create_double 用于创建一个ArkTSæ•°å—(double类型)的值。 cpp部分代ç ```cpp #include "napi/native_api.h" static napi_value CreateDouble(napi_env env, napi_callback_info info) { double value = 1.234; // 创建ArkTSä¸çš„doubleæ•°å— napi_value result = nullptr; napi_status status = napi_create_double(env, value, &result); if (status != napi_ok) { // 处ç†é”™è¯¯ napi_throw_error(env, nullptr, "Failed to create double value"); } return result; } ``` 接å£å£°æ˜Ž ```ts // index.d.ts export const createDouble: () => number; ``` ArkTS侧示例代ç ```ts import hilog from '@ohos.hilog' import testNapi from 'libentry.so' hilog.info(0x0000, 'testTag','Test Node-API napi_create_double: ' + testNapi.createDouble()); ``` 以上代ç 如果è¦åœ¨native cpp䏿‰“å°æ—¥å¿—,需在CMakeLists.txtæ–‡ä»¶ä¸æ·»åР以䏋é…置信æ¯ï¼ˆå¹¶æ·»åŠ å¤´æ–‡ä»¶ï¼š#include "hilog/log.h"): ```text // CMakeLists.txt add_definitions( "-DLOG_DOMAIN=0xd0d0" ) add_definitions( "-DLOG_TAG=\"testTag\"" ) target_link_libraries(entry PUBLIC libhilog_ndk.z.so) ```