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 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 80Use **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 82For more information, see [Wrapping a Native Object in an ArkTS Object](use-napi-object-wrap.md). 83 84### napi_define_class 85 86Use **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. 87 88For more information, see [Wrapping a Native Object in an ArkTS Object](use-napi-object-wrap.md). 89 90### napi_wrap 91 92Use **napi_wrap** to wrap a native instance in an ArkTS object. 93 94> **NOTE** 95> 96> If **js_object** is not of the object or function type, **napi_object_expected** will be returned. 97 98### napi_unwrap 99 100Use **napi_unwrap** to unwrap a native instance from an ArkTS object and obtain the pointer to the data. 101 102> **NOTE** 103> 104> If **js_object** is not of the object or function type, **napi_object_expected** will be returned. 105 106### napi_remove_wrap 107 108Use **napi_remove_wrap** to remove the wrapping after a native instance is unwrapped from an ArkTS object. 109 110> **NOTE** 111> 112> If **js_object** is not of the object or function type, **napi_object_expected** will be returned. 113 114CPP code: 115 116```cpp 117#include <hilog/log.h> 118#include <string> 119#include "napi/native_api.h" 120 121struct Object { 122 std::string name; 123 int32_t age; 124}; 125 126static void DerefItem(napi_env env, void *data, void *hint) { 127 // Optional native callback, which is used to release the native instance when the ArkTS object is garbage-collected. 128 OH_LOG_INFO(LOG_APP, "Node-API DerefItem"); 129 (void)hint; 130} 131 132static napi_value Wrap(napi_env env, napi_callback_info info) 133{ 134 OH_LOG_INFO(LOG_APP, "Node-API wrap"); 135 // Initialize the native object. 136 struct Object *obj = new struct Object(); 137 obj->name = "lilei"; 138 obj->age = 18; 139 size_t argc = 1; 140 napi_value toWrap; 141 // Call napi_wrap to wrap the native object in an ArkTS object. 142 napi_get_cb_info(env, info, &argc, &toWrap, NULL, NULL); 143 napi_wrap(env, toWrap, reinterpret_cast<void *>(obj), DerefItem, NULL, NULL); 144 145 return toWrap; 146} 147 148static napi_value RemoveWrap(napi_env env, napi_callback_info info) 149{ 150 OH_LOG_INFO(LOG_APP, "Node-API removeWrap"); 151 size_t argc = 1; 152 napi_value wrapped = nullptr; 153 void *data = nullptr; 154 // Call napi_remove_wrap to remove the wrapping. 155 napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr); 156 napi_remove_wrap(env, wrapped, &data); 157 158 return nullptr; 159} 160 161static napi_value UnWrap(napi_env env, napi_callback_info info) 162{ 163 OH_LOG_INFO(LOG_APP, "Node-API unWrap"); 164 size_t argc = 1; 165 napi_value wrapped = nullptr; 166 napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr); 167 // Call napi_unwrap to retrieve the data from the ArkTS object and print the data. 168 struct Object *data; 169 napi_unwrap(env, wrapped, reinterpret_cast<void **>(&data)); 170 OH_LOG_INFO(LOG_APP, "Node-API name: %{public}s", data->name.c_str()); 171 OH_LOG_INFO(LOG_APP, "Node-API age: %{public}d", data->age); 172 return nullptr; 173} 174``` 175 176API declaration: 177 178```ts 179// index.d.ts 180export const wrap: (obj: Object) => Object; 181export const unWrap: (obj: Object) => void; 182export const removeWrap: (obj: Object) => void; 183``` 184 185ArkTS code: 186 187```ts 188import hilog from '@ohos.hilog' 189import testNapi from 'libentry.so' 190try { 191 class Obj {} 192 let obj: Obj = {}; 193 testNapi.wrap(obj) 194 testNapi.unWrap(obj) 195 testNapi.removeWrap(obj) 196} catch (error) { 197 hilog.error(0x0000, 'testTag', 'Test Node-API error: %{public}s', error.message); 198} 199``` 200 201To 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"**. 202 203```text 204// CMakeLists.txt 205add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 206add_definitions( "-DLOG_TAG=\"testTag\"" ) 207target_link_libraries(entry PUBLIC libhilog_ndk.z.so) 208``` 209