1# Working with Classes Using Node-API
2
3## Introduction
4
5Node-API provides APIs for managing ArkTS classes, for example, defining an ArkTS class and creating an ArkTS instance, in C/C++.
6
7## Basic Concepts
8
9To begin with, it is important to understand the following basic concepts:
10
11- Class: a template used to create an object. It provides a way to define object properties and methods in a structured manner. Classes in ArkTS are based on prototypes and added with unique syntax and semantics.
12- Instance: an object created from a class. A class defines the structure and behavior of an object, and an instance is a specific representation of a class. Instantiating a class allows access to the properties and methods defined in the class. Each instance has its own property values.
13
14## Available APIs
15
16The following table lists the APIs for manipulating ArkTS classes.  
17| API| Description|
18| -------- | -------- |
19| napi_new_instance | Creates an instance based on the given constructor.|
20| napi_get_new_target | Obtains the **new.target** of the constructor call.|
21| napi_define_class | Defines an ArkTS class corresponding to the C/C++ class. This API binds an ArkTS class and a C/C++ class.|
22| napi_wrap | Wraps a native object into an ArkTS object. This API allows the methods and properties of a native object to be called from ArkTS.|
23| napi_unwrap | Unwraps the native object from an ArkTS object.|
24| napi_remove_wrap | Removes the wrapping after the native object is unwrapped from an ArkTS object.|
25
26## Example
27
28If you are just starting out with Node-API, see [Node-API Development Process](use-napi-process.md). The following demonstrates only the C++ and ArkTS code involved in the class-related APIs.
29
30### napi_new_instance
31
32Use **napi_new_instance** to create an ArkTS instance with the given constructor. This API returns an instance that can be called from ArkTS.
33
34CPP code:
35
36```cpp
37static napi_value NewInstance(napi_env env, napi_callback_info info)
38{
39    // Pass in and parse parameters. The first parameter is the constructor, and the second parameter is the parameters of the constructor.
40    size_t argc = 2;
41    napi_value args[2] = {nullptr};
42    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
43    // Call napi_new_instance to create an instance and return the instance created.
44    napi_value result = nullptr;
45    napi_new_instance(env, args[0], 1, &args[1], &result);
46    return result;
47}
48```
49
50API declaration:
51
52```ts
53// index.d.ts
54export const newInstance: (obj: Object, param: string) => Object
55```
56
57ArkTS code:
58
59```ts
60import hilog from '@ohos.hilog'
61import testNapi from 'libentry.so'
62class Fruit {
63  name: string;
64  constructor(name: string) {
65    this.name = name;
66  }
67}
68// Call the function and use the variable obj to hold the instance created.
69let obj = testNapi.newInstance(Fruit, 'test');
70// Print the obj object.
71hilog.info(0x0000, 'Node-API', 'napi_new_instance %{public}s', JSON.stringify(obj));
72```
73
74### napi_get_new_target
75
76Use **napi_get_new_target** to obtain **new.target** of a constructor. In ArkTS, **new.target** is a meta property used to determine whether a constructor was called using the **new** operator.
77
78For more information, see [Wrapping a Native Object in an ArkTS Object](use-napi-object-wrap.md).
79
80### napi_define_class
81
82Use **napi_define_class** to define an ArkTS class. This API creates an ArkTS class and associates the methods and properties of the ArkTS class with those of a C/C++ class.
83
84For more information, see [Wrapping a Native Object in an ArkTS Object](use-napi-object-wrap.md).
85
86### napi_wrap
87
88Use **napi_wrap** to wrap a native instance in an ArkTS object.
89
90### napi_unwrap
91
92Use **napi_unwrap** to unwrap a native instance from an ArkTS object and obtain the pointer to the data.
93
94### napi_remove_wrap
95
96Use **napi_remove_wrap** to remove the wrapping after a native instance is unwrapped from an ArkTS object.
97
98CPP code:
99
100```cpp
101#include <hilog/log.h>
102#include <string>
103#include "napi/native_api.h"
104
105struct Object {
106    std::string name;
107    int32_t age;
108};
109
110static void DerefItem(napi_env env, void *data, void *hint) {
111    // Optional native callback, which is used to release the native instance when the ArkTS object is garbage-collected.
112    OH_LOG_INFO(LOG_APP, "Node-API DerefItem");
113    (void)hint;
114}
115
116static napi_value Wrap(napi_env env, napi_callback_info info)
117{
118    OH_LOG_INFO(LOG_APP, "Node-API wrap");
119    // Initialize the native object.
120    struct Object *obj = new struct Object();
121    obj->name = "lilei";
122    obj->age = 18;
123    size_t argc = 1;
124    napi_value toWrap;
125    // Call napi_wrap to wrap the native object in an ArkTS object.
126    napi_get_cb_info(env, info, &argc, &toWrap, NULL, NULL);
127    napi_wrap(env, toWrap, reinterpret_cast<void *>(obj), DerefItem, NULL, NULL);
128
129    return toWrap;
130}
131
132static napi_value RemoveWrap(napi_env env, napi_callback_info info)
133{
134    OH_LOG_INFO(LOG_APP, "Node-API removeWrap");
135    size_t argc = 1;
136    napi_value wrapped = nullptr;
137    void *data = nullptr;
138    // Call napi_remove_wrap to remove the wrapping.
139    napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr);
140    napi_remove_wrap(env, wrapped, &data);
141
142    return nullptr;
143}
144
145static napi_value UnWrap(napi_env env, napi_callback_info info)
146{
147    OH_LOG_INFO(LOG_APP, "Node-API unWrap");
148    size_t argc = 1;
149    napi_value wrapped = nullptr;
150    napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr);
151    // Call napi_unwrap to retrieve the data from the ArkTS object and print the data.
152    struct Object *data;
153    napi_unwrap(env, wrapped, reinterpret_cast<void **>(&data));
154    OH_LOG_INFO(LOG_APP, "Node-API name: %{public}s", data->name.c_str());
155    OH_LOG_INFO(LOG_APP, "Node-API age: %{public}d", data->age);
156    return nullptr;
157}
158```
159
160API declaration:
161
162```ts
163// index.d.ts
164export const wrap: (obj: Object) => Object;
165export const unWrap: (obj: Object) => void;
166export const removeWrap: (obj: Object) => void;
167```
168
169ArkTS code:
170
171```ts
172import hilog from '@ohos.hilog'
173import testNapi from 'libentry.so'
174try {
175    class Obj {}
176    let obj: Obj = {};
177    testNapi.wrap(obj)
178    testNapi.unWrap(obj)
179    testNapi.removeWrap(obj)
180} catch (error) {
181    hilog.error(0x0000, 'testTag', 'Test Node-API error: %{public}s', error.message);
182}
183```
184
185To print logs in the native CPP, add the following information to the **CMakeLists.txt** file and add the header file by using **#include "hilog/log.h"**.
186
187```text
188// CMakeLists.txt
189add_definitions( "-DLOG_DOMAIN=0xd0d0" )
190add_definitions( "-DLOG_TAG=\"testTag\"" )
191target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
192```
193