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