1# 使用Node-API接口进行primitive类相关开发
2
3## 简介
4
5在使用Node-API接口时,开发人员可以实现在Node-API模块中与ArkTS对象的交互,并进行数据转换和获取特定对象的操作,它们在不同的场景中发挥着重要的作用,使开发人员能够更灵活地处理ArkTS值和对象。
6
7## 基本概念
8
9在使用Node-API操作ArkTS对象时,有一些基本概念需要了解:
10
11- **ArkTS值到C/C++类型的转换:** 在Node-API模块中,可以使用Node-API函数将ArkTS值转换为C/C++的数据类型,如将ArkTS数值转换为C/C++的整数、将ArkTS字符串转换为C/C++的字符数组等。同样,也可以将C/C++的数据类型转换为ArkTS值,以便将结果返回给ArkTS代码。
12
13## 场景和功能介绍
14
15以下接口用于从C/C++代码中与ArkTS进行交互,传递数据并执行操作,它们的使用场景如下:
16| 接口 | 描述 |
17| -------- | -------- |
18| napi_coerce_to_bool | 用于将给定的ArkTS value强转成ArkTS boolean值。 |
19| napi_coerce_to_number | 用于将给定的ArkTS value强转成ArkTS number。 |
20| napi_coerce_to_object | 用于将给定的ArkTS value强转成ArkTS Object。 |
21| napi_coerce_to_string | 用于将给定的ArkTS value强转成ArkTS string。 |
22| napi_get_boolean | 用于根据给定的C boolean值,获取ArkTS boolean值。 |
23| napi_get_value_bool | 用于根据给定的ArkTS boolean值,获取等价的C/C++布尔值。 |
24| napi_get_global | 用于获取全局ArkTS对象,以便在C/C++中访问和操纵全局对象。 |
25| napi_get_null | 用于获取ArkTS null。 |
26| napi_get_undefined | 用于获取ArkTS undefined。 |
27
28## 使用示例
29
30Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
31
32### napi_coerce_to_bool
33
34用于将给定的ArkTS value强转成ArkTS boolean值。
35
36cpp部分代码
37
38```cpp
39#include "napi/native_api.h"
40
41static napi_value CoerceToBool(napi_env env, napi_callback_info info)
42{
43    // 获取并解析传进的参数
44    size_t argc = 1;
45    napi_value args[1] = {nullptr};
46    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
47    // 将传入的值转换为布尔值
48    napi_value result = nullptr;
49    napi_coerce_to_bool(env, args[0], &result);
50    //返回强转之后的ArkTS boolean值
51    return result;
52}
53```
54
55接口声明
56
57```ts
58// index.d.ts
59export const coerceToBool: <T>(data: T) => boolean;
60```
61
62ArkTS侧示例代码
63
64```ts
65import hilog from '@ohos.hilog'
66import testNapi from 'libentry.so'
67
68let value = testNapi.coerceToBool<number>(0);
69let str = testNapi.coerceToBool<string>('111111111');
70let obj = new Object();
71let res = testNapi.coerceToBool<Object>(obj);
72let result = testNapi.coerceToBool<null>(null);
73// false
74hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_bool:%{public}s', value);
75// true
76hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_bool:%{public}s', str);
77// true
78hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_bool:%{public}s', res);
79// false
80hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_bool:%{public}s', result);
81```
82
83### napi_coerce_to_number
84
85用于将给定的ArkTS value强转成ArkTS number。
86
87cpp部分代码
88
89```cpp
90#include "napi/native_api.h"
91
92static napi_value CoerceToNumber(napi_env env, napi_callback_info info)
93{
94    // 获取并解析传进的参数
95    size_t argc = 1;
96    napi_value args[1] = {nullptr};
97    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
98    // 将传入的值转换为number值
99    napi_value result = nullptr;
100    napi_coerce_to_number(env, args[0], &result);
101    return result;
102}
103```
104
105接口声明
106
107```ts
108// index.d.ts
109export const coerceToNumber: <T>(data: T) => number;
110```
111
112ArkTS侧示例代码
113
114```ts
115import hilog from '@ohos.hilog'
116import testNapi from 'libentry.so'
117
118let value = testNapi.coerceToNumber<string>('2556');
119let str = testNapi.coerceToNumber<string>('sssss');
120let bool = testNapi.coerceToNumber<boolean>(true);
121hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_number:%{public}d', value);
122// 返回的为NAN
123hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_number:%{public}d', str);
124// 返回的是1
125hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_number:%{public}d', bool);
126```
127
128### napi_coerce_to_object
129
130用于将给定的ArkTS value强转成ArkTS Object。
131
132cpp部分代码:
133
134```cpp
135#include "napi/native_api.h"
136
137static napi_value CoerceToObject(napi_env env, napi_callback_info info)
138{
139    // 获取并解析传进的参数
140    size_t argc = 1;
141    napi_value args[1] = {nullptr};
142    napi_value obj = nullptr;
143    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
144    // 将传入的值转换为Object值
145    napi_coerce_to_object(env, args[0], &obj);
146    return obj;
147}
148```
149
150接口声明
151
152```ts
153// index.d.ts
154export const coerceToObject: <T>(data: T) => Object;
155```
156
157ArkTS侧示例代码
158
159```ts
160import hilog from '@ohos.hilog'
161import testNapi from 'libentry.so'
162
163let value = testNapi.coerceToObject<string>('222222');
164let result = testNapi.coerceToObject<number>(111);
165hilog.info(0x0000, 'testTag', 'Node-API coerceToObject:%{public}s.', typeof result);
166if (typeof value === 'object') {
167  hilog.info(0x0000, 'testTag', 'Node-API The value is an object.');
168} else {
169  hilog.info(0x0000, 'testTag', 'Node-API The value is not an object.');
170}
171```
172
173### napi_coerce_to_string
174
175用于将给定的ArkTS value强转成ArkTS string。
176
177cpp部分代码
178
179```cpp
180#include "napi/native_api.h"
181
182static napi_value CoerceToString(napi_env env, napi_callback_info info)
183{
184    // 获取并解析传进的参数
185    size_t argc = 1;
186    napi_value args[1] = {nullptr};
187    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
188    // 将传入的值转换为string
189    napi_value str = nullptr;
190    napi_coerce_to_string(env, args[0], &str);
191    return str;
192}
193```
194
195接口声明
196
197```ts
198// index.d.ts
199export const coerceToString: <T>(data: T) => string;
200```
201
202ArkTS侧示例代码
203
204```ts
205import hilog from '@ohos.hilog'
206import testNapi from 'libentry.so'
207
208let value = testNapi.coerceToString<number>(212);
209let obj = new Object();
210let res = testNapi.coerceToString<Object>(obj);
211let bool = testNapi.coerceToString<boolean>(false);
212hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_string:%{public}s', value);
213hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_string:%{public}s', typeof res);
214hilog.info(0x0000, 'testTag', 'Test Node-API napi_coerce_to_string:%{public}s', bool);
215```
216
217### napi_get_boolean
218
219用于根据给定的C boolean值,获取等价的ArkTS Boolean对象。
220
221cpp部分代码
222
223```cpp
224#include "napi/native_api.h"
225
226static napi_value GetBoolean(napi_env env, napi_callback_info info)
227{
228    // 传入两个参数并解析
229    size_t argc = 2;
230    napi_value argv[2];
231    napi_valuetype data, value;
232    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
233    // 判断两个参数类型值
234    napi_typeof(env, argv[0], &data);
235    napi_typeof(env, argv[1], &value);
236
237    napi_value returnValue = nullptr;
238    // 判断两个类型值是否相等,获取结果的布尔值
239    napi_get_boolean(env, data == value, &returnValue);
240    // 返回结果
241    return returnValue;
242}
243```
244
245接口声明
246
247```ts
248// index.d.ts
249export const getBoolean: <T>(data: T, value: String) => boolean;
250```
251
252ArkTS侧示例代码
253
254```ts
255import hilog from '@ohos.hilog'
256import testNapi from 'libentry.so'
257
258let value = testNapi.getBoolean<number>(1, '1');
259let data = testNapi.getBoolean<string>('sss', '1');
260hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_boolean:%{public}s', value);
261hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_boolean:%{public}s', data);
262```
263
264### napi_get_value_bool
265
266使用这个函数将ArkTS中的布尔值转为等价的C布尔值。
267
268cpp部分代码
269
270```cpp
271#include "napi/native_api.h"
272
273static napi_value GetValueBool(napi_env env, napi_callback_info info)
274{
275    size_t argc = 1;
276    napi_value args[1] = {nullptr};
277
278    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
279    bool bool_c = false;
280    napi_status status = napi_get_value_bool(env, args[0], &bool_c);
281    if (status == napi_boolean_expected) {
282        // 如果napi_get_value_bool成功会返回napi_ok,如果传入一个非布尔值则会返回napi_boolean_expected
283        return nullptr;
284    }
285    napi_value boolNapi = nullptr;
286    napi_get_boolean(env, bool_c, &boolNapi);
287    return boolNapi;
288}
289```
290
291接口声明
292
293```ts
294// index.d.ts
295export const getValueBool: (value: boolean | string) => boolean | void;
296```
297
298ArkTS侧示例代码
299
300```ts
301import hilog from '@ohos.hilog'
302import testNapi from 'libentry.so'
303
304// 分别传入布尔值和非布尔值检测接口,传入布尔值将返回原布尔值,传入其他类型返回undefined
305hilog.info(0x0000, 'Node-API', 'get_value_bool_not_bool %{public}s', testNapi.getValueBool('你好123'));
306hilog.info(0x0000, 'Node-API', 'get_value_bool_true %{public}s', testNapi.getValueBool(true));
307hilog.info(0x0000, 'Node-API', 'get_value_bool_false %{public}s', testNapi.getValueBool(false));
308```
309
310### napi_get_global
311
312用于获取全局ArkTS对象。该函数的主要作用是获取表示ArkTS全局对象的napi_value,使得C/C++模块能够与ArkTS运行时的全局对象进行交互。
313
314cpp部分代码
315
316```cpp
317#include "napi/native_api.h"
318
319static napi_value GetGlobal(napi_env env, napi_callback_info info)
320{
321    napi_value global = nullptr;
322    // 获取global对象
323    napi_get_global(env, &global);
324    return global;
325}
326```
327
328接口声明
329
330```ts
331// index.d.ts
332export const getGlobal: () => Object;
333```
334
335ArkTS侧示例代码
336
337```ts
338import hilog from '@ohos.hilog'
339import testNapi from 'libentry.so'
340
341let globalObj = testNapi.getGlobal();
342// 判断获取的global是否具有global的自身属性
343hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_global:%{public}s', globalObj.hasOwnProperty!("undefined"));
344```
345
346### napi_get_null
347
348用于获取ArkTS中的null。
349
350cpp部分代码
351
352```cpp
353#include "napi/native_api.h"
354
355static napi_value GetNull(napi_env env, napi_callback_info info)
356{
357    napi_value nullValue = nullptr;
358    napi_get_null(env, &nullValue);
359    return nullValue;
360}
361```
362
363接口声明
364
365```ts
366// index.d.ts
367export const getNull: () => null;
368```
369
370ArkTS侧示例代码
371
372```ts
373import hilog from '@ohos.hilog'
374import testNapi from 'libentry.so'
375
376let value = testNapi.getNull();
377hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_null:%{public}s', value);
378```
379
380### napi_get_undefined
381
382用于获取ArkTS中的undefined。
383
384cpp部分代码
385
386```cpp
387#include "napi/native_api.h"
388
389static napi_value GetUndefined(napi_env env, napi_callback_info info)
390{
391    // 获取并解析传进的参数
392    size_t argc = 1;
393    napi_value args[1] = {nullptr};
394    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
395
396    napi_value value = nullptr;
397    napi_get_undefined(env, &value);
398    // 判断传入参数的类型与undefined值的类型是否一致
399    bool isEqual = false;
400    napi_strict_equals(env, args[0], value, &isEqual);
401    // 参数与undefined值相等
402    napi_value result = nullptr;
403    // 返回判断类型之后的结果,相等返回为true,不等则为false
404    napi_get_boolean(env, isEqual, &result);
405    return result;
406}
407```
408
409接口声明
410
411```ts
412// index.d.ts
413export const getUndefined: (value: undefined) => boolean;
414```
415
416ArkTS侧示例代码
417
418```ts
419import hilog from '@ohos.hilog'
420import testNapi from 'libentry.so'
421
422let data: undefined = undefined;
423let value = testNapi.getUndefined(data);
424hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_undefined:%{public}s', value);
425```
426
427以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
428
429```text
430// CMakeLists.txt
431add_definitions( "-DLOG_DOMAIN=0xd0d0" )
432add_definitions( "-DLOG_TAG=\"testTag\"" )
433target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
434```
435