• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Working with Class 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
32Call **napi_new_instance** to create an ArkTS instance with the given constructor. This API returns an instance that can be called from ArkTS.
33
34> **NOTE**
35>
36> If **constructor** is not of the function type, **napi_function_expected** will be returned.
37
38CPP code:
39
40```cpp
41static napi_value NewInstance(napi_env env, napi_callback_info info)
42{
43    // Pass in and parse parameters. The first parameter is the constructor, and the second parameter is the parameters of the constructor.
44    size_t argc = 2;
45    napi_value args[2] = {nullptr};
46    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
47    // Call napi_new_instance to create an instance and return the instance created.
48    napi_value result = nullptr;
49    napi_new_instance(env, args[0], 1, &args[1], &result);
50    return result;
51}
52```
53
54API declaration:
55
56```ts
57// index.d.ts
58export const newInstance: (obj: Object, param: string) => Object;
59```
60
61ArkTS code:
62
63```ts
64import hilog from '@ohos.hilog';
65import testNapi from 'libentry.so';
66class Fruit {
67  name: string;
68  constructor(name: string) {
69    this.name = name;
70  }
71}
72// Call the function and use the variable obj to hold the instance created.
73let obj = testNapi.newInstance(Fruit, 'test');
74// Print the information about the object obj.
75hilog.info(0x0000, 'Node-API', 'napi_new_instance %{public}s', JSON.stringify(obj));
76```
77
78### napi_get_new_target
79
80Call **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.
81
82
83For more information, see [Wrapping a Native Object in an ArkTS Object](use-napi-object-wrap.md).
84
85### napi_define_class
86
87Call **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.
88
89
90For more information, see [Wrapping a Native Object in an ArkTS Object](use-napi-object-wrap.md).
91
92### napi_wrap
93
94Call **napi_wrap** to wrap a native instance in an ArkTS object.
95
96> **NOTE**
97>
98> If **js_object** is not of the object or function type, **napi_object_expected** will be returned.
99
100### napi_unwrap
101
102Call **napi_unwrap** to unwrap a native instance from an ArkTS object and obtain the pointer to the data.
103
104> **NOTE**
105>
106> If **js_object** is not of the object or function type, **napi_object_expected** will be returned.
107
108### napi_remove_wrap
109
110Call **napi_remove_wrap** to remove the wrapping after a native instance is unwrapped from an ArkTS object.
111
112> **NOTE**
113>
114> If **js_object** is not of the object or function type, **napi_object_expected** will be returned.
115
116CPP code:
117
118```cpp
119#include <hilog/log.h>
120#include <string>
121#include "napi/native_api.h"
122
123static constexpr int INT_ARG_18 = 18; // Age: 18 years old
124
125struct Object {
126    std::string name;
127    int32_t age;
128};
129
130static void DerefItem(napi_env env, void *data, void *hint) {
131    // Optional native callback, which is used to release the native instance when the ArkTS object is garbage-collected.
132    OH_LOG_INFO(LOG_APP, "Node-API DerefItem");
133    (void)hint;
134}
135
136static napi_value Wrap(napi_env env, napi_callback_info info)
137{
138    OH_LOG_INFO(LOG_APP, "Node-API wrap");
139    // Initialize the native object.
140    struct Object *obj = new struct Object();
141    obj->name = "liLei";
142    obj->age = INT_ARG_18;
143    size_t argc = 1;
144    napi_value toWrap;
145    // Call napi_wrap to wrap the native object in an ArkTS object.
146    napi_get_cb_info(env, info, &argc, &toWrap, NULL, NULL);
147    napi_status status = napi_wrap(env, toWrap, reinterpret_cast<void *>(obj), DerefItem, NULL, NULL);
148    if (status != napi_ok) {
149        // Proactively release the memory.
150        delete obj;
151    }
152
153    return toWrap;
154}
155
156static napi_value RemoveWrap(napi_env env, napi_callback_info info)
157{
158    OH_LOG_INFO(LOG_APP, "Node-API removeWrap");
159    size_t argc = 1;
160    napi_value wrapped = nullptr;
161    void *data = nullptr;
162    // Call napi_remove_wrap to remove the wrapping.
163    napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr);
164    napi_remove_wrap(env, wrapped, &data);
165
166    return nullptr;
167}
168
169static napi_value UnWrap(napi_env env, napi_callback_info info)
170{
171    OH_LOG_INFO(LOG_APP, "Node-API unWrap");
172    size_t argc = 1;
173    napi_value wrapped = nullptr;
174    napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr);
175    // Call napi_unwrap to retrieve the data from the ArkTS object and print the data.
176    struct Object *data;
177    napi_unwrap(env, wrapped, reinterpret_cast<void **>(&data));
178    OH_LOG_INFO(LOG_APP, "Node-API name: %{public}s", data->name.c_str());
179    OH_LOG_INFO(LOG_APP, "Node-API age: %{public}d", data->age);
180    return nullptr;
181}
182```
183
184API declaration:
185
186```ts
187// index.d.ts
188export const wrap: (obj: Object) => Object;
189export const unWrap: (obj: Object) => void;
190export const removeWrap: (obj: Object) => void;
191```
192
193ArkTS code:
194
195```ts
196import hilog from '@ohos.hilog';
197import testNapi from 'libentry.so';
198try {
199    class Obj {}
200    let obj: Obj = {};
201    testNapi.wrap(obj)
202    testNapi.unWrap(obj)
203    testNapi.removeWrap(obj)
204} catch (error) {
205    hilog.error(0x0000, 'testTag', 'Test Node-API error: %{public}s', error.message);
206}
207```
208
209To 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"**.
210
211```text
212// CMakeLists.txt
213add_definitions( "-DLOG_DOMAIN=0xd0d0" )
214add_definitions( "-DLOG_TAG=\"testTag\"" )
215target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
216```
217