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