1# 使用Node-API接口进行object相关开发
2
3## 简介
4
5使用Node-API接口进行object相关开发,处理ArkTS对象的基本操作的功能,例如创建对象、获取原型、冻结和密封对象,检查对象的类型等。这些操作是在处理ArkTS对象时非常常见的,提供了一种与ArkTS对象交互的方式。
6
7## 基本概念
8
9在Node-API接口开发中,经常需要定义和操作对象。例如,创建一个API接口,该接口接受一个对象作为输入参数,对该对象执行某些操作,并返回一个结果对象。在这个过程中,需要确保接口的定义清晰、规范,并且与对象的属性和方法相兼容。
10
11- **接口(API)**:接口定义了组件之间的交互协议,包括输入参数、输出结果以及可能的错误处理。通过接口,组件可以相互调用和交换数据,而无需了解对方的内部实现细节。
12- **对象(Object)**:在ArkTS,对象是一种复合数据类型,允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值,而方法则是对象可以执行的操作。
13
14## 场景和功能介绍
15
16以下Node-API接口主要用于操作和管理ArkTS对象,使用场景介绍:
17| 接口 | 描述 |
18| -------- | -------- |
19| napi_get_prototype | 当需要获取一个ArkTS对象的原型时,可以使用这个接口。通过这个接口可以在C/C++中获取到这个原型对象。 |
20| napi_create_object | 在Node-API模块中创建一个默认的ArkTS对象。 |
21| napi_object_freeze | 当需要确保一个对象不会被修改时(immutable),可以使用这个接口来冻结该对象,使其属性不可更改。 |
22| napi_object_seal | 类似于napi_object_freeze,napi_object_seal用于密封给定的对象,使其属性不可添加或删除,但可以修改属性的值。 |
23| napi_typeof | 在处理传入的ArkTS值时,可以使用这个接口来获取其类型,以便进行相应的处理。 |
24| napi_instanceof | 当需要在Node-API模块中确定一个对象是否为特定构造函数的实例时,可以使用这个接口。 |
25| napi_type_tag_object | 可以将指针的特定值与ArkTS对象关联起来,这对于一些自定义的内部对象标记非常有用。 |
26| napi_check_object_type_tag | 使用此接口可以检查给定的对象上是否关联了特定类型的标记。 |
27| napi_create_symbol | 创建一个ArkTS Symbol对象。 |
28| napi_create_external | 用于创建一个ArkTS外部对象,该对象可以用于将C/C++中的自定义数据结构或对象传递到ArkTS中,并且可以在ArkTS中访问其属性和方法。 |
29| napi_get_value_external | 用于获得napi_create_external创建的绑定了外部数据的ArkTS值,此函数可以在ArkTS和C/C++之间传递数据。 |
30
31这些接口为开发人员提供了在Node-API模块中处理ArkTS对象的灵活性和功能性,可以实现从创建对象到管理对象属性以及类型检查等多种操作。
32
33## 使用示例
34
35Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
36
37### napi_get_prototype
38
39可以获得给定ArkTS对象的prototype。
40
41cpp部分代码
42
43```cpp
44#include "napi/native_api.h"
45
46static napi_value GetPrototype(napi_env env, napi_callback_info info)
47{
48    // 获取并解析传参
49    size_t argc = 1;
50    napi_value args[1] = {nullptr};
51    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
52    napi_value result = nullptr;
53    // 获取此对象的原型对象,将结果返回到napi_value类型的变量result中
54    napi_get_prototype(env, args[0], &result);
55    return result;
56}
57```
58
59接口声明
60
61```ts
62// index.d.ts
63export const getPrototype: (object: Object) => Object;
64```
65
66ArkTS侧示例代码
67
68```ts
69import hilog from '@ohos.hilog'
70import testNapi from 'libentry.so'
71// 定义一个类
72class Person {
73  // 属性
74  name: string;
75  age: number;
76  // 构造函数
77  constructor(name: string, age: number) {
78    this.name = name;
79    this.age = age;
80  }
81}
82// 创建类的实例
83const person = new Person('Alice', 30);
84// 传入实例对象,获取该对象的原型
85let applePrototype = testNapi.getPrototype(person);
86// 判断通过testNapi.getPrototype()函数获取到的原型是不是apple的原型
87// 在DevEco Studio 4.1及以后的版本中,由于ArkTS没有原型的概念,因此尝试进行原型赋值或相关操作时,将会触发错误提示'Prototype assignment is not supported (arkts-no-prototype-assignment)',以下代码需在ts文件中执行
88if (applePrototype === Person.prototype) {
89  hilog.info(0x0000, 'Node-API', 'get_prototype_success');
90} else {
91  hilog.info(0x0000, 'Node-API', 'get_prototype_fail');
92}
93```
94
95### napi_create_object
96
97用于在Node-API模块中创建一个空的ArkTS对象。
98
99cpp部分代码
100
101```cpp
102#include "napi/native_api.h"
103
104napi_value NewObject(napi_env env, napi_callback_info info)
105{
106    napi_value object = nullptr;
107    // 创建一个空对象
108    napi_create_object(env, &object);
109    // 设置对象的属性
110    napi_value name = nullptr;
111    // 设置属性名为"name"
112    napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &name);
113    napi_value value = nullptr;
114    // 设置属性值为"Hello from Node-API!"
115    napi_create_string_utf8(env, "Hello from Node-API!", NAPI_AUTO_LENGTH, &value);
116    // 将属性设置到对象上
117    napi_set_property(env, object, name, value);
118    return object;
119}
120```
121
122接口声明
123
124```ts
125// index.d.ts
126export const createObject: () => { name: string };
127```
128
129ArkTS侧示例代码
130
131```ts
132import hilog from '@ohos.hilog'
133import testNapi from 'libentry.so'
134try {
135  const myObject = testNapi.createObject();
136  hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_object: %{public}s', myObject.name);
137} catch (error) {
138  hilog.error(0x0000, 'testTag', 'Test Node-API napi_create_object errorCode: %{public}s, errorMessage: %{public}s', error.code, error.message);
139}
140```
141
142### napi_object_freeze
143
144用于冻结给定的ArkTS对象。冻结对象后,无法再向对象添加新的属性或方法,也无法修改已有属性或方法的值。
145
146cpp部分代码
147
148```cpp
149#include "hilog/log.h"
150#include "napi/native_api.h"
151
152static napi_value ObjectFreeze(napi_env env, napi_callback_info info)
153{
154    // 接受一个ArkTS侧传入的object
155    size_t argc = 1;
156    napi_value argv[1] = {nullptr};
157    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
158
159    // 调用接口napi_object_freeze将传入的object冻结
160    napi_value objFreeze = argv[0];
161    napi_status status = napi_object_freeze(env, objFreeze);
162    if (status == napi_ok) {
163        OH_LOG_INFO(LOG_APP, "Node-API napi_object_freeze success");
164    }
165    // 将冻结后的object传回ArkTS侧
166    return objFreeze;
167}
168```
169
170接口声明
171
172```ts
173// index.d.ts
174export interface Obj {
175  data: number
176  message: string
177}
178export const objectFreeze: (objFreeze: Object) => Obj;
179```
180
181ArkTS侧示例代码
182
183```ts
184import hilog from '@ohos.hilog'
185import testNapi from 'libentry.so'
186try {
187  class Obj {
188    data: number = 0
189    message: string = ""
190  }
191  let obj: Obj = {data: 0, message: "hello world"};
192  let objFreeze = testNapi.objectFreeze(obj);
193  hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_freeze: %{public}s', (objFreeze.data = 1));
194} catch (error) {
195  hilog.error(0x0000, 'testTag', 'Test Node-API napi_object_freeze error: %{public}s', error.message);
196}
197```
198
199### napi_object_seal
200
201封闭一个对象后,无法向其添加新的属性,也无法删除或修改现有属性的可配置性。但是,可以继续修改已有属性的值。
202
203cpp部分代码
204
205```cpp
206#include "hilog/log.h"
207#include "napi/native_api.h"
208
209static napi_value ObjectSeal(napi_env env, napi_callback_info info)
210{
211    // 接受一个ArkTS侧传入的object
212    size_t argc = 1;
213    napi_value argv[1] = {nullptr};
214    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
215    // 调用接口napi_object_seal将传入的object封闭,使其无法添加新的属性
216    napi_value objSeal = argv[0];
217    napi_status status = napi_object_seal(env, objSeal);
218    if (status == napi_ok) {
219        OH_LOG_INFO(LOG_APP, "Node-API napi_object_seal success");
220    }
221    // 将封闭后的object传回ArkTS侧
222    return objSeal;
223}
224```
225
226接口声明
227
228```ts
229// index.d.ts
230export interface Obj {
231  data: number
232  message: string
233  id: number
234}
235export const objectSeal : (objSeal: Object) => Obj;
236```
237
238ArkTS侧示例代码
239
240```ts
241import hilog from '@ohos.hilog'
242import testNapi from 'libentry.so'
243try {
244  class Obj {
245    data: number = 0
246    message: string = ""
247    // 可选属性
248    address?: number = 0
249  }
250  let obj: Obj = { data: 0, message: "hello world"};
251  let objSeal = testNapi.objectSeal(obj);
252  hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_seal: %{public}s', objSeal.message);
253  objSeal.data = 1;
254  hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_seal: %{public}d', objSeal.data);
255  hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_seal: %{public}d', (objSeal.id = 1));
256} catch (error) {
257  hilog.error(0x0000, 'testTag', 'Test Node-API napi_object_seal error: %{public}s', error.message);
258}
259```
260
261### napi_typeof
262
263获取给定ArkTS value的ArkTS Type。
264
265cpp部分代码
266
267```cpp
268#include "napi/native_api.h"
269
270static napi_value NapiTypeOf(napi_env env, napi_callback_info info)
271{
272    // 接受一个入参
273    size_t argc = 1;
274    napi_value args[1] = {nullptr};
275    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
276
277    // 调用napi_typeof判断传入ArkTS参数类型
278    napi_valuetype valueType;
279    napi_status status = napi_typeof(env, args[0], &valueType);
280    if (status != napi_ok) {
281        napi_throw_error(env, nullptr, "Node-API napi_typeof fail");
282        return nullptr;
283    }
284    // 将结果转成napi_value类型返回。
285    napi_value returnValue = nullptr;
286    switch(valueType) {
287    case napi_undefined:
288        napi_create_string_utf8(env, "Input type is napi_undefined", NAPI_AUTO_LENGTH, &returnValue);
289        break;
290    case napi_null:
291        napi_create_string_utf8(env, "Input type is napi_null", NAPI_AUTO_LENGTH, &returnValue);
292        break;
293    case napi_boolean:
294        napi_create_string_utf8(env, "Input type is napi_boolean", NAPI_AUTO_LENGTH, &returnValue);
295        break;
296    case napi_number:
297        napi_create_string_utf8(env, "Input type is napi_number", NAPI_AUTO_LENGTH, &returnValue);
298        break;
299    case napi_string:
300        napi_create_string_utf8(env, "Input type is napi_string", NAPI_AUTO_LENGTH, &returnValue);
301        break;
302    case napi_object:
303        napi_create_string_utf8(env, "Input type is napi_object", NAPI_AUTO_LENGTH, &returnValue);
304        break;
305    case napi_function:
306        napi_create_string_utf8(env, "Input type is napi_function", NAPI_AUTO_LENGTH, &returnValue);
307        break;
308    case napi_bigint:
309        napi_create_string_utf8(env, "Input type is napi_bigint", NAPI_AUTO_LENGTH, &returnValue);
310        break;
311    default:
312        napi_create_string_utf8(env, "unknown", NAPI_AUTO_LENGTH, &returnValue);
313    }
314
315    return returnValue;
316}
317```
318
319接口声明
320
321```ts
322// index.d.ts
323export const napiTypeOf : <T>(value: T) => string | void;
324```
325
326ArkTS侧示例代码
327
328```ts
329import hilog from '@ohos.hilog'
330import testNapi from 'libentry.so'
331try {
332  let varUndefined: undefined;
333  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varUndefined));
334  let varNull: null = null;
335  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varNull));
336  let varTrue= true;
337  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varTrue));
338  let varNum = 1;
339  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varNum));
340  let varString = "str";
341  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varString));
342  class Obj {
343    id: number = 0
344    name: string = ""
345  }
346  let varObject: Obj = {id: 1, name: "LiLei"};
347  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varObject));
348  const addNum = (a: number, b: number): number => a * b;
349  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(addNum));
350  let varBigint = BigInt("1234567890123456789012345678901234567890");
351  hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varBigint));
352} catch (error) {
353  hilog.error(0x0000, 'testTag', 'Test Node-API napi_typeof error: %{public}s', error.message);
354}
355```
356
357### napi_instanceof
358
359用于检查一个对象是否是指定构造函数的实例。
360
361cpp部分代码
362
363```cpp
364#include "napi/native_api.h"
365
366static napi_value NapiInstanceOf(napi_env env, napi_callback_info info)
367{
368    // 接受两个入参
369    size_t argc = 2;
370    napi_value args[2] = {nullptr};
371    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
372    // 调用napi_instanceof接口判断给定object是否为给定constructor的实例
373    bool result = true;
374    napi_status status = napi_instanceof(env, args[0], args[1], &result);
375    if (status != napi_ok) {
376        napi_throw_error(env, nullptr, "Node-API napi_instanceof fail");
377        return nullptr;
378    }
379    // 将结果转成napi_value类型返回
380    napi_value returnValue = nullptr;
381    napi_get_boolean(env, result, &returnValue);
382
383    return returnValue;
384}
385```
386
387接口声明
388
389```ts
390// index.d.ts
391export const napiInstanceOf: (date: Object, construct: Object) => boolean | void;
392```
393
394ArkTS侧示例代码
395
396```ts
397import hilog from '@ohos.hilog'
398import testNapi from 'libentry.so'
399try {
400  class Person {
401    name: string;
402    age: number;
403
404    constructor(name: string, age: number) {
405      this.name = name;
406      this.age = age;
407    }
408  }
409  const person = new Person("Alice", 30);
410  class Obj {
411    data: number = 0
412    message: string = ""
413  }
414  let obj: Obj = { data: 0, message: "hello world"};
415  hilog.info(0x0000, 'testTag', 'Test Node-API napi_instanceof: %{public}s', testNapi.napiInstanceOf(person, Person));
416  hilog.info(0x0000, 'testTag', 'Test Node-API napi_instanceof: %{public}s', testNapi.napiInstanceOf(obj, Person));
417} catch (error) {
418  hilog.error(0x0000, 'testTag', 'Test Node-API napi_instanceof error: %{public}s', error.message);
419}
420```
421
422### napi_type_tag_object
423
424使用类型标签type_tag来标记ArkTS对象,后续可以更精确地识别ArkTS对象。
425
426### napi_check_object_type_tag
427
428验证一个ArkTS对象是否带有特定类型标签。
429
430类型标签提供了一种在Node-API模块和ArkTS对象之间建立强类型关联的机制,使得原生代码能够更准确地识别和处理特定的ArkTS对象。
431
432cpp部分代码
433
434```cpp
435#include "napi/native_api.h"
436
437#define NUMBERINT_FOUR 4
438// 定义一个静态常量napi_type_tag数组存储类型标签
439static const napi_type_tag TagsData[NUMBERINT_FOUR] = {
440    {0x9e4b2449547061b3, 0x33999f8a6516c499},
441    {0x1d55a794c53a726d, 0x43633f509f9c944e},
442    // 用于表示无标签或默认标签
443    {0, 0},
444    {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0},
445};
446
447static napi_value SetTypeTagToObject(napi_env env, napi_callback_info info)
448{
449    // 获取函数调用信息和参数
450    size_t argc = 2;
451    napi_value args[2] = {nullptr};
452    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
453    // 获取索引数字转换为napi_value
454    int32_t index = 0;
455    napi_get_value_int32(env, args[1], &index);
456    // 给参数(对象)设置类型标签
457    napi_status status = napi_type_tag_object(env, args[0], &TagsData[index]);
458    if (status != napi_ok) {
459        napi_throw_error(env, "Reconnect error", "napi_type_tag_object failed");
460        return nullptr;
461    }
462    // 将bool结果转换为napi_value并返回
463    napi_value result = nullptr;
464    napi_get_boolean(env, true, &result);
465    return result;
466}
467
468static napi_value CheckObjectTypeTag(napi_env env, napi_callback_info info)
469{
470    // 获取函数调用信息和参数
471    size_t argc = 2;
472    napi_value args[2] = {nullptr};
473    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
474    // 获取索引数字转换为napi_value
475    int32_t index = 0;
476    napi_get_value_int32(env, args[1], &index);
477    // 检查对象的类型标签
478    bool checkResult = true;
479    napi_check_object_type_tag(env, args[0], &TagsData[index], &checkResult);
480    // 将bool结果转换为napi_value并返回
481    napi_value checked = nullptr;
482    napi_get_boolean(env, checkResult, &checked);
483
484    return checked;
485}
486```
487
488接口声明
489
490```ts
491// index.d.ts
492export const setTypeTagToObject: (obj: Object, index: number) => boolean | void;
493export const checkObjectTypeTag: (obj: Object, index: number) => boolean;
494```
495
496ArkTS侧示例代码
497
498```ts
499import hilog from '@ohos.hilog'
500import testNapi from 'libentry.so'
501class Obj {
502  data: number = 0
503  message: string = ""
504}
505let objA: Obj = { data: 0, message: "hello world"};
506let objB: Obj = { data: 10, message: "typeTag"};
507hilog.info(0x0000, 'testTag', 'Test Node-API napi_type_tag_object objA -> 0: %{public}s', testNapi.setTypeTagToObject(objA, 0));
508hilog.info(0x0000, 'testTag', 'Test Node-API napi_type_tag_object objB -> 0: %{public}s', testNapi.setTypeTagToObject(objB, 0));
509hilog.info(0x0000, 'testTag', 'Test Node-API napi_check_object_type_tag objA -> 0: %{public}s', testNapi.checkObjectTypeTag(objA, 0));
510hilog.info(0x0000, 'testTag', 'Test Node-API napi_check_object_type_tag objB -> 1: %{public}s', testNapi.checkObjectTypeTag(objB, 1));
511```
512
513### napi_create_external
514
515创建包装自定义的C/C++对象并将其公开给ArkTS代码。这种情况下,我们可以使用napi_create_external来创建一个包含指向自定义对象的指针的Node-API值,以便让ArkTS代码能够访问和操作该对象。
516
517cpp部分代码
518
519```cpp
520#include <cstdlib>
521#include <string>
522#include "napi/native_api.h"
523
524// 用于释放外部数据的回调函数
525void finalizeCallback(napi_env env, void *data, void *hint) {
526    // 释放外部数据
527    free(data);
528}
529
530static napi_value GetExternalType(napi_env env, napi_callback_info info)
531{
532    size_t argc = 1;
533    napi_value args[1] = {nullptr};
534    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
535    // 获取参数的数据类型
536    napi_valuetype valueType;
537    napi_typeof(env, args[0], &valueType);
538    napi_value returnValue = nullptr;
539    if (valueType == napi_external) {
540        // 如果数据类型是napi_external,则返回true
541        napi_get_boolean(env, true, &returnValue);
542    } else {
543        napi_get_boolean(env, false, &returnValue);
544    }
545    return returnValue;
546}
547
548static napi_value CreateExternal(napi_env env, napi_callback_info info)
549{
550    // 设置外部数据大小为10
551    const size_t dataSize = 10;
552    // 分配外部数据
553    void *data = malloc(dataSize);
554    // 初始化外部数据
555    memset(data, 0, dataSize);
556    napi_value result = nullptr;
557    // 返回带有外部数据的对象
558    napi_status status = napi_create_external(env, data, finalizeCallback, nullptr, &result);
559    if (status != napi_ok) {
560        napi_throw_error(env, nullptr, " Node-API Failed to create external data");
561        return nullptr;
562    }
563    return result;
564}
565```
566
567接口声明
568
569```ts
570// index.d.ts
571export const createExternal: () => Object;
572export const getExternalType: (externalData: Object) => boolean;
573```
574
575ArkTS侧示例代码
576
577```ts
578import hilog from '@ohos.hilog'
579import testNapi from 'libentry.so'
580const externalData = testNapi.createExternal();
581hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_external:%{public}s', testNapi.getExternalType(externalData));
582```
583
584### napi_get_value_external
585
586napi_create_external可以创建包装自定义的C/C++对象并将其公开给ArkTS代码,而napi_get_value_external就是用来获得napi_create_external所创建的外部对象的。
587
588cpp部分代码
589
590```cpp
591#include "napi/native_api.h"
592
593static int external = 5;
594static napi_value GetValueExternal(napi_env env, napi_callback_info info)
595{
596    // 创建外部数据
597    int* data = &external;
598    napi_value setExternal = nullptr;
599    napi_create_external(env, data, nullptr, nullptr, &setExternal);
600    // 获得外部数据的值
601    void *getExternal;
602    napi_get_value_external(env, setExternal, &getExternal);
603    // 返回获得到的外部数据
604    napi_value result = nullptr;
605    napi_create_int32(env, *(int *)getExternal, &result);
606    return result;
607}
608```
609
610接口声明
611
612```ts
613// index.d.ts
614export const getValueExternal: () => number;
615```
616
617ArkTS侧示例代码
618
619```ts
620import hilog from '@ohos.hilog'
621import testNapi from 'libentry.so'
622hilog.info(0x0000, 'Node-API', 'get_value_external:%{public}d', testNapi.getValueExternal());
623```
624
625### napi_create_symbol
626
627用于创建一个新的Symbol。Symbol是一种特殊的数据类型,用于表示唯一的标识符。与字符串或数字不同,符号的值是唯一的,即使两个符号具有相同的描述,它们也是不相等的。符号通常用作对象属性的键,以确保属性的唯一性。
628
629cpp部分代码
630
631```cpp
632#include "napi/native_api.h"
633
634static napi_value CreateSymbol(napi_env env, napi_callback_info info)
635{
636    napi_value result = nullptr;
637    const char *des = "only";
638    // 使用napi_create_string_utf8创建描述字符串
639    napi_create_string_utf8(env, des, NAPI_AUTO_LENGTH, &result);
640    napi_value returnSymbol = nullptr;
641    // 创建一个symbol类型,并返回
642    napi_create_symbol(env, result, &returnSymbol);
643    return returnSymbol;
644}
645```
646
647接口声明
648
649```ts
650// index.d.ts
651export const createSymbol : () => symbol;
652```
653
654ArkTS侧示例代码
655
656```ts
657import hilog from '@ohos.hilog'
658import testNapi from 'libentry.so'
659let varSymbol = testNapi.createSymbol();
660hilog.info(0x0000, 'Node-API', 'createSymbol:%{public}s', typeof varSymbol);
661```
662
663以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
664
665```text
666// CMakeLists.txt
667add_definitions( "-DLOG_DOMAIN=0xd0d0" )
668add_definitions( "-DLOG_TAG=\"testTag\"" )
669target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
670```
671