• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用Node-API接口进行函数创建和调用
2<!--Kit: NDK-->
3<!--Subsystem: arkcompiler-->
4<!--Owner: @xliu-huanwei; @shilei123; @huanghello-->
5<!--Designer: @shilei123-->
6<!--Tester: @kirl75; @zsw_zhushiwei-->
7<!--Adviser: @fang-jinxu-->
8
9## 简介
10
11函数调用允许开发者从Node-API模块中调用ArkTS函数并传递参数,或在Node-API模块中创建ArkTS函数。
12
13## 基本概念
14
15函数是一种非常重要的编程概念,可以执行特定的任务或操作、提高代码的可读性、把复杂任务简化、提高代码复用性以及支持代码的组织与管理。每个函数可以负责不同的功能,提供一种将代码模块化和组织结构化的方式,使其更易于理解、维护和重用。
16
17## 场景和功能介绍
18
19| 接口 | 描述 |
20| -------- | -------- |
21| napi_get_cb_info | 当需要从给定的callback info中获取有关调用的参数信息和this指针时,可使用此接口。 |
22| napi_call_function | 当需要在Node-API模块中对ArkTS侧函数进行调用时,可使用此接口。 |
23| napi_create_function | 当需要将C/C++函数创建为ArkTS函数时,可以使用此接口。 |
24
25## 使用示例
26
27Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
28## napi_get_cb_info
29
30获取有关函数调用的详细信息。
31
32cpp部分代码
33
34```cpp
35#include "napi/native_api.h"
36// 获取ArkTS侧入参的的参数信息
37static napi_value GetCbArgs(napi_env env, napi_callback_info info)
38{
39    size_t argc = 1;
40    napi_value args[1] = {nullptr};
41    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
42    return args[0];
43}
44// 获取ArkTS侧入参的参数个数
45static napi_value GetCbArgQuantity(napi_env env, napi_callback_info info)
46{
47    size_t argc = 0;
48    napi_value result = nullptr;
49    napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
50    napi_create_int32(env, argc, &result);
51    return result;
52}
53// 获取ArkTS侧this参数
54static napi_value GetCbContext(napi_env env, napi_callback_info info)
55{
56    napi_value thisArg = nullptr;
57    napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr);
58    return thisArg;
59}
60```
61<!-- @[napi_get_cb_info](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/cpp/napi_init.cpp) -->
62
63接口声明
64
65```ts
66// index.d.ts
67export const getCbArgs: <T>(arg: T) => T;
68// getCbArgQuantity的入参由用户自定义,在此用例中,我们用两个入参,一个是string,一个是number
69export const getCbArgQuantity: (str: string, num: number) => number;
70export const getCbContext: () => Object;
71```
72<!-- @[napi_get_cb_info_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/cpp/types/libentry/Index.d.ts) -->
73
74ArkTS 侧示例代码
75
76```ts
77import { hilog } from '@kit.PerformanceAnalysisKit';
78import testNapi from 'libentry.so';
79function summation(arr: Array<number>) {
80  let sum: number = 0;
81  for (let i = 0; i < arr.length; i++) {
82    sum += arr[i];
83  }
84  return sum;
85}
86const str = 'message';
87const arr = [0, 1, 2, 3, 4, 5];
88const num = 526;
89class Student {
90  name: string;
91  age: number;
92  score: number;
93  constructor(name: string, age: number, score: number) {
94    this.name = name;
95    this.age = age;
96    this.score = score;
97  }
98}
99let student = new Student('Alice', 18, 100);
100// 获取参数
101hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get string arg:%{public}s', testNapi.getCbArgs(str));
102hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get array arg:%{public}s ', testNapi.getCbArgs(arr).toString());
103hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get num arg:%{public}d ', testNapi.getCbArgs(num));
104hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get undefined arg:%{public}s ', testNapi.getCbArgs(undefined));
105hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get object arg:%{public}s ', JSON.stringify(testNapi.getCbArgs(student)));
106hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get function arg:%{public}d ', testNapi.getCbArgs(summation(arr)));
107// 获取参数个数
108hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get arg quantity:%{public}d ', testNapi.getCbArgQuantity(str, num));
109// 获取上下文
110hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_cb_info get thisArg:%{public}s ', testNapi.getCbContext().toString());
111```
112<!-- @[ark_napi_get_cb_info](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/ets/pages/Index.ets) -->
113
114## napi_call_function
115
116在C/C++侧对ArkTS函数进行调用。
117注意事项:napi_call_function传入的argv的长度必须大于等于argc声明的数量,并且每个元素都应初始化为nullptr。
118
119cpp部分代码
120
121```cpp
122#include "napi/native_api.h"
123
124static napi_value CallFunction(napi_env env, napi_callback_info info)
125{
126    size_t argc = 1;
127    napi_value argv[1] = {nullptr};
128    // 获取ArkTS侧入参
129    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
130    // 获取全局对象,这里用global是因为napi_call_function的第二个参数是JS函数的this入参。
131    napi_value global = nullptr;
132    napi_get_global(env, &global);
133    // 调用ArkTS方法
134    napi_value result = nullptr;
135    // 调用napi_call_function时传入的argv的长度必须大于等于argc声明的数量,且被初始化成nullptr
136    napi_call_function(env, global, argv[0], argc, argv, &result);
137    return result;
138}
139
140static napi_value ObjCallFunction(napi_env env, napi_callback_info info)
141{
142    // 获取ArkTS侧传递的两个参数
143    size_t argc = 2;
144    napi_value argv[2] = {nullptr};
145    // 获取ArkTS侧入参
146    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
147    // 调用ArkTS方法
148    napi_value result = nullptr;
149    // 调用napi_call_function时传入的argv的长度必须大于等于argc声明的数量,且被初始化成nullptr
150    napi_call_function(env, argv[0], argv[1], argc, argv, &result);
151    return result;
152}
153```
154<!-- @[napi_call_function](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/cpp/napi_init.cpp) -->
155
156接口声明
157
158```ts
159// index.d.ts
160export const callFunction: (func: Function) => number;
161export const objCallFunction: (obj: Object, func: Function) => number;
162```
163<!-- @[napi_call_function_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/cpp/types/libentry/Index.d.ts) -->
164
165ArkTS 侧示例代码
166
167```ts
168import { hilog } from '@kit.PerformanceAnalysisKit';
169import testNapi from 'libentry.so';
170
171function returnNumber() {
172  return 10;
173}
174class Person {
175  age(): number {
176    return 11;
177  }
178}
179const person = new Person();
180hilog.info(0x0000, 'testTag', 'Test Node-API call_function:%{public}d', testNapi.callFunction(returnNumber));
181hilog.info(0x0000, 'testTag', 'Test Node-API call_function:%{public}d', testNapi.objCallFunction(person,person.age));
182```
183<!-- @[ark_napi_call_function](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/ets/pages/Index.ets) -->
184
185## napi_create_function
186
187将一个C/C++函数包装为可在ArkTS中调用的函数,并返回一个表示该函数的napi_value。
188
189cpp部分代码
190
191```cpp
192#include "napi/native_api.h"
193
194static napi_value CalculateArea(napi_env env, napi_callback_info info)
195{
196    // 获取ArkTS侧传递的两个参数
197    size_t argc = 2;
198    napi_value args[2] = {nullptr};
199    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
200    double width = 0;
201    napi_get_value_double(env, args[0], &width);
202    double height = 0;
203    napi_get_value_double(env, args[1], &height);
204    napi_value area = nullptr;
205    napi_create_double(env, width * height, &area);
206    return area;
207}
208
209EXTERN_C_START
210static napi_value Init(napi_env env, napi_value exports) {
211    napi_value fn = nullptr;
212    napi_create_function(env, nullptr, 0, CalculateArea, nullptr, &fn);
213    napi_set_named_property(env, exports, "calculateArea", fn);
214    return exports;
215}
216EXTERN_C_END
217```
218<!-- @[napi_create_function](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/cpp/napi_init.cpp) -->
219
220接口声明
221
222```ts
223// index.d.ts
224export const calculateArea: (width: number, height: number) => number;
225```
226<!-- @[napi_create_function_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/cpp/types/libentry/Index.d.ts) -->
227
228ArkTS 侧示例代码
229
230```ts
231import { hilog } from '@kit.PerformanceAnalysisKit';
232import testNapi from 'libentry.so';
233
234hilog.info(0x0000, 'testTag', 'Test Node-API create_function:%{public}d ', testNapi.calculateArea(1.2, 4));
235```
236<!-- @[ark_napi_create_function](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIFunction/entry/src/main/ets/pages/Index.ets) -->
237
238以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
239
240```text
241// CMakeLists.txt
242add_definitions( "-DLOG_DOMAIN=0xd0d0" )
243add_definitions( "-DLOG_TAG=\"testTag\"" )
244target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so)
245```
246