1# Working with Functions Using Node-API
2
3## Introduction
4
5Node-API provides APIs for calling ArkTS functions and passing parameters or creating ArkTS methods in C/C++.
6
7## Basic Concepts
8
9Functions are blocks of reusable code that performs specific tasks or operations. You can define functions to implement different operations. Functions provide a way to modularize and structure code, helping make your code more organized, reusable, and maintainable.
10
11## Available APIs
12
13| API| Description|
14| -------- | -------- |
15| napi_get_cb_info | Obtains detailed information about the call, such as the parameters and **this** pointer, from the given callback information.|
16| napi_call_function | Calls an ArkTS function from a C/C++ addon.|
17| napi_create_function | Creates an ArkTS function based on a C/C++ function.|
18
19## Example
20
21If 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 related to function invocation. The **napi_create_function** API is different. For details, see the example.
22
23## napi_get_cb_info
24
25Use **napi_get_cb_info** to obtain detailed information about function calls.
26
27CPP code:
28
29```cpp
30#include "napi/native_api.h"
31// Obtain information about the parameters passed from ArkTS.
32static napi_value GetCbArgs(napi_env env, napi_callback_info info)
33{
34    size_t argc = 1;
35    napi_value args[1] = {nullptr};
36    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
37    return args[0];
38}
39// Obtain the number of parameters passed from ArkTS.
40static napi_value GetCbArgQuantity(napi_env env, napi_callback_info info)
41{
42    size_t argc = 0;
43    napi_value result = nullptr;
44    napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
45    napi_create_int32(env, argc, &result);
46    return result;
47}
48// Obtain thisArg passed from ArkTS.
49static napi_value GetCbContext(napi_env env, napi_callback_info info)
50{
51    napi_value thisArg = nullptr;
52    napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr);
53    return thisArg;
54}
55```
56
57API declaration:
58
59```ts
60// index.d.ts
61export const getCbArgs: <T>(arg: T) => T;
62// The input parameters of getCbArgQuantity are customized. In this example, two input parameters are used: string and number.
63export const getCbArgQuantity: (str: string, num: number) => number;
64export const getCbContext: () => Object;
65```
66
67ArkTS code:
68
69```ts
70import hilog from '@ohos.hilog'
71import testNapi from 'libentry.so'
72function summation(arr: Array<number>) {
73  let sum: number = 0;
74  for (let i = 0; i < arr.length; i++) {
75    sum += arr[i];
76  }
77  return sum;
78}
79const str = 'message';
80const arr = [0, 1, 2, 3, 4, 5];
81const num = 526;
82class Student {
83  name: string;
84  age: number;
85  score: number;
86  constructor(name: string, age: number, score: number) {
87    this.name = name;
88    this.age = age;
89    this.score = score;
90  }
91}
92let student = new Student('Alice', 18, 100);
93// Obtain parameters.
94hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get string arg:%{public}s', testNapi.getCbArgs(str));
95hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get array arg:%{public}s ', testNapi.getCbArgs(arr).toString());
96hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get num arg:%{public}d ', testNapi.getCbArgs(num));
97hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get undefined arg:%{public}s ', testNapi.getCbArgs(undefined));
98hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get object arg:%{public}s ', JSON.stringify(testNapi.getCbArgs(student)));
99hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get function arg:%{public}d ', testNapi.getCbArgs(summation(arr)));
100// Obtain the number of parameters.
101hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get arg quantity:%{public}d ', testNapi.getCbArgQuantity(str, num));
102// Obtain the context.
103hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get thisArg:%{public}s ', testNapi.getCbContext().toString());
104```
105
106## napi_call_function
107
108Use **napi_call_function** to call an ArkTS function from a C/C++ addon.
109
110> **NOTE**<br>The length of **argv** passed by **napi_call_function** must be greater than or equal to the value of **argc** and must be initialized to **nullptr**.
111
112CPP code:
113
114```cpp
115#include "napi/native_api.h"
116
117static napi_value CallFunction(napi_env env, napi_callback_info info)
118{
119    size_t argc = 1;
120    napi_value argv[1] = {nullptr};
121    // Obtain the parameters passed from ArkTS.
122    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
123    // Obtain the global object. Here, global is used because the second parameter of napi_call_function is the this parameter of the ArkTS function.
124    napi_value global = nullptr;
125    napi_get_global(env, &global);
126    // Call the ArkTS method.
127    napi_value result = nullptr;
128    // The length of argv passed by napi_call_function must be greater than or equal to the value of argc and must be initialized to nullptr.
129    napi_call_function(env, global, argv[0], argc, argv, &result);
130    return result;
131}
132
133static napi_value ObjCallFunction(napi_env env, napi_callback_info info)
134{
135    // Obtain the two parameters passed from ArkTS.
136    size_t argc = 2;
137    napi_value argv[2] = {nullptr};
138    // Obtain the parameters passed from ArkTS.
139    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
140    // Call the ArkTS method.
141    napi_value result = nullptr;
142    // The length of argv passed by napi_call_function must be greater than or equal to the value of argc and must be initialized to nullptr.
143    napi_call_function(env, argv[0], argv[1], argc, argv, &result);
144    return result;
145}
146```
147
148API declaration:
149
150```ts
151// index.d.ts
152export const callFunction: (func: Function) => number;
153export const objCallFunction: (obj: Object, func: Function) => number;
154```
155
156ArkTS code:
157
158```ts
159import hilog from '@ohos.hilog'
160import testNapi from 'libentry.so'
161
162function returnNumber() {
163  return 10;
164}
165class Person {
166  age(): number {
167    return 11;
168  }
169}
170const person = new Person();
171hilog.info(0x0000, 'testTag', 'Test Node-API call_function:%{public}d', testNapi.callFunction(returnNumber));
172hilog.info(0x0000, 'testTag', 'Test Node-API call_function:%{public}d', testNapi.objCallFunction(person,person.age));
173```
174
175## napi_create_function
176
177Use **napi_create_function** to create an ArkTS function object in native code, which allows calling into the native code from ArkTS. This API returns a **napi_value** that represents the function created.
178
179CPP code:
180
181```cpp
182#include "napi/native_api.h"
183
184static napi_value CalculateArea(napi_env env, napi_callback_info info)
185{
186    // Obtain the two parameters passed from ArkTS.
187    size_t argc = 2;
188    napi_value args[2] = {nullptr};
189    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
190    double width = 0;
191    napi_get_value_double(env, args[0], &width);
192    double height = 0;
193    napi_get_value_double(env, args[1], &height);
194    napi_value area = nullptr;
195    napi_create_double(env, width * height, &area);
196    return area;
197}
198
199EXTERN_C_START
200static napi_value Init(napi_env env, napi_value exports) {
201    napi_value fn = nullptr;
202    napi_create_function(env, nullptr, 0, CalculateArea, nullptr, &fn);
203    napi_set_named_property(env, exports, "calculateArea", fn);
204    return exports;
205}
206EXTERN_C_END
207```
208
209API declaration:
210
211```ts
212// index.d.ts
213export const calculateArea: (width: number, height: number) => number;
214```
215
216ArkTS code:
217
218```ts
219import hilog from '@ohos.hilog'
220import testNapi from 'libentry.so'
221
222hilog.info(0x0000, 'testTag', 'Test Node-API create_function:%{public}d ', testNapi.calculateArea(1.2, 4));
223```
224
225To 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"**.
226
227```text
228// CMakeLists.txt
229add_definitions( "-DLOG_DOMAIN=0xd0d0" )
230add_definitions( "-DLOG_TAG=\"testTag\"" )
231target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
232```
233