• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# NAPI框架生成工具使用说明
2## 简介
3
4NAPI框架生成工具支持三种入口,分别是可执行程序、VS Code插件、DevEco Studio上使用的IntelliJ插件,使用者可以根据自己的需要选择合适的工具。
5
61.可执行文件下载路径如下(由于网络原因,可能会导致有的下载链接失效,因此提供了以下三个下载链接):
7
8[可执行文件下载链接1](http://ftpkaihongdigi.i234.me:5000/sharing/yaRiKSjBI)
9
10[可执行文件下载链接2](http://ftp.kaihong.com:5000/fsdownload/yaRiKSjBI/)
11
12[可执行文件下载链接3](http://ftp.kaihongdigi.com:5000/fsdownload/yaRiKSjBI/)
13
14访问密码:kaihong
15
16压缩包解压密码:kaihong20231121
17
18DevEco Studio上使用的IntelliJ插件下载路径如下:
19
20[DevEco Studio上使用的IntelliJ插件下载链接](https://plugins.jetbrains.com/plugin/19593-napi-generator/versions)
21
22## 工具介绍
23
24通过NAPI框架生成工具,使用者可输入一个接口定义的ts文件,一键生成NAPI框架代码、业务代码框架、GN脚本等文件,并使用生成的NAPI接口及功能。使用者也可以输入一个定义方法的.h头文件,反向生成ts文件。
25
26![](../figures/pic-frm.png)
27
28## 预检查
29
30napi_generator的可执行程序方式和插件方式都具有预检查的功能,如果.d.ts文件中存在语法错误,那么执行的时候命令行会打印出错误信息,指出代码中存在错误的行号。使用效果如下:
31
32	joey@joey-virtual-machine:~/code/napi_test$ ./napi_generator-linux -f @ohos.napitest.d.ts
33	@ohos.napitest.d.ts (33,12): Identifier expected.
34	@ohos.napitest.d.ts (33,13): ';' expected.
35	@ohos.napitest.d.ts (33,13): An identifier or keyword cannot immediately follow a numeric literal.
36	@ohos.napitest.d.ts (33,13): Cannot find name 'shutdownDevice'.
37	@ohos.napitest.d.ts (33,28): Cannot find name 'reason'.
38	@ohos.napitest.d.ts (33,34): ',' expected.
39	@ohos.napitest.d.ts (33,36): 'string' only refers to a type, but is being used as a value here.
40	@ohos.napitest.d.ts (33,43): ';' expected.
41	@ohos.napitest.d.ts (33,49): Expression expected.
42
43	joey@joey-virtual-machine:~/code/napi_test$
44
45@ohos.napitest.d.ts (33,49),其中括号中the first 参数含义为行号,第二个参数含义为列号。
46
47预检查的触发方式与生成框架的入口一致,使用方法参见生成框架描述。
48
49## 生成框架
50
51### 自动配置业务代码用例
52
531.ts文件用例
54
55 [@ohos.napitest.d.ts](https://gitee.com/openharmony/napi_generator/blob/master/test/dts2cpp/ts/@ohos.napitest.d.ts)
56
57注册关键字说明
58
59(1) registerXXX/unRegisterXXX
60
61register与unRegister成对使用, registerXXX用于注册回调,其参数即为注册的回调函数,注册之后在其它普通方法中即可在C++层调用registerXXX注册的回调函数;unRegisterXXX用于注销回调,其参数即为需要注销的回调函数,注销之后将无法再在C++层调用注销的回调函数。如:
62
63```
64export class NodeISayHello
65{
66    ...
67    // register注册回调
68    registerCallbackfunc(cb : (wid: number) => string);
69    // unRegister注销回调
70    unRegisterCallbackfunc(cb : (wid: number) => string);
71    ...
72}
73```
74
75其中注册/注销的回调方法为箭头函数 (wid: number) => string。注册回调之后,工具会生成回调方法CallbackfuncCallback,业务代码中用户自行定义回调时机进而通过回调接口调用回调,若回调被注销,则业务代码无法触发该回调。
76
77(2) addXXX/removeXXX   onXXX
78
79addXXX与removeXXX成对使用,addXXX用于注册回调,其参数为class对象, 将需要注册的回调函数放于class中,其写法为onXXX,class中可以有多个onXXX回调函数;removeXXX用于注销回调,其参数为class对象,用于注销addXXX注册的回调。如:
80
81```
82export class NodeISayHello
83{
84    ...
85    // 注册object回调
86    addSayHelloListener(listener: NodeISayHelloListener);
87    // 注销object回调
88    removeSayHelloListener(listener: NodeISayHelloListener);
89    ...
90}
91...
92export class NodeISayHelloListener
93{   // 定义回调
94    onSayHelloStart(info: SayInfo);
95    onSayHelloEnd(info: SayInfo);
96}
97```
98
99其中注册/注销的回调方法为onSayHelloStart(info: SayInfo); onSayHelloEnd(info: SayInfo); 注册回调之后,工具会生成两个回调接口供用户调用,业务代码中用户自行定义回调时机进而通过回调接口调用回调,若回调被注销,则业务代码无法触发回调。
100
1012.自动配置业务代码用例使用的cfg.json
102
103```
104[
105  {
106    "genPath": "E:\\napi_aboutTest\\testcase_napi_intellijPlugin\\generatorCode",
107    "includeName": "../serviceCode/NodeISayHello.h",
108    "cppName": "../serviceCode/NodeISayHello.cpp",
109    "interfaceName": "NodeISayHello::sayHello",
110    "serviceCode": "napitest::NodeISayHello *p = new napitest::NodeISayHello();\n    p->sayHello(from, to, sayType);\n    delete p;"
111  },
112  {
113    "genPath": "E:\\napi_aboutTest\\testcase_napi_intellijPlugin\\generatorCode",
114    "includeName": "../serviceCode/NodeISayHello.h",
115    "cppName": "../serviceCode/NodeISayHello.cpp",
116    "interfaceName": "NodeISayHello::sayHi",
117    "serviceCode": "napitest::NodeISayHello *p = new napitest::NodeISayHello();\n    p->sayHi(from, to, sayType);\n    delete p;"
118  },
119  {
120    "genPath": "E:\\napi_aboutTest\\testcase_napi_intellijPlugin\\generatorCode",
121    "includeName": "../serviceCode/NodeISayHello.h",
122    "cppName": "../serviceCode/NodeISayHello.cpp",
123    "interfaceName": "funcTest",
124    "serviceCode": "out = napitest::funcTest(v);"
125  },
126  {
127    "genPath": "E:\\napi_aboutTest\\testcase_napi_intellijPlugin\\generatorCode",
128    "includeName": "../serviceCode/NodeISayHello.h",
129    "cppName": "../serviceCode/NodeISayHello.cpp",
130    "interfaceName": "NodeISayHello::sayHelloWithResponse",
131    "serviceCode": "napitest::NodeISayHello *p = new napitest::NodeISayHello();\n    p->sayHelloWithResponse(from, to, sayType);\n    delete p;"
132  }
133]
134```
135
1363.自动配置业务代码使用的业务代码用例
137
138业务代码用例如下:
139
140serviceCode/NodeISayHello.h
141
142```
143#ifndef IMPL_NODEISAYHELLO_H
144#define IMPL_NODEISAYHELLO_H
145
146#include <string>
147#include <memory>
148
149namespace napitest {
150class NodeISayHello;
151class NodeISayHello {
152public:
153    void sayHello(std::string& from, std::string& to, uint32_t& sayType);
154    void sayHi(std::string& from, std::string& to, uint32_t& sayType);
155    void sayHelloWithResponse(std::string& from, std::string& to, uint32_t& sayType);
156};
157std::string funcTest(bool& v);
158}
159#endif // IMPL_NODEISAYHELLO_H
160```
161
162serviceCode/NodeISayHello.cpp
163
164```
165#include "NodeISayHello.h"
166#include "../generatorCode/napitest.h"
167#include "hilog/log.h"
168static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0XD002E00, "NAPITESTNAPILayer"};
169#define NAPITEST_LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \
170    	"%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__)
171
172namespace napitest {
173  // 1. 打印from, to, enum sayType的值
174  // 2. 调用注册的NodeISayHelloListenerSayHelloStart(info: SayInfo)方法
175  //    工具提供的业务接口(回调) void NodeISayHello::SayHelloListenerSayHelloStartCallback(SayInfo& info)
176  // 3. 调用注册的NodeISayHelloListenerSayHelloEnd(info: SayInfo)方法
177  //    工具提供的业务接口(回调) void NodeISayHello::SayHelloListenerSayHelloEndCallback(SayInfo& info)
178void NodeISayHello::sayHello(std::string& from, std::string& to, uint32_t& sayType)
179{
180    // 1.打印
181    NAPITEST_LOGI("NAPITEST_LOGI sayHello from = %s\r\n", from.c_str());
182    NAPITEST_LOGI("NAPITEST_LOGI sayHello to = %s\r\n", to.c_str());
183    NAPITEST_LOGI("NAPITEST_LOGI sayHello sayType = %d\r\n", sayType);
184
185    // 2.调用回调
186    napitest::napitest_interface::SayInfo info1;
187    info1.from = "js1";
188    uint32_t a = 992;
189    info1.fromId.emplace(a);
190    uint32_t b = 1014;
191    info1.toId.emplace(b);
192    info1.to = "native1";
193    info1.content = "hello1";
194    info1.saidTime = "123456789";
195    info1.isEnd = false;
196
197    napitest::napitest_interface::SayInfo info2;
198    info2.from = "native";
199    uint32_t c = 101;
200    info2.fromId.emplace(c);
201    uint32_t d = 99;
202    info2.toId.emplace(d);
203    info2.to = "js";
204    info2.content = "hello";
205    info2.saidTime = "987654321";
206    info2.isEnd = true;
207    // 业务代码调用 onSayHelloStart callback
208    NAPITEST_LOGI("NAPITEST_LOGI NodeISayHelloListener_onSayHelloStartCallback begin\r\n");
209    napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloStartCallback(info1);
210    NAPITEST_LOGI("NAPITEST_LOGI NodeISayHelloListener_onSayHelloStartCallback end\r\n");
211    // 业务代码调用 onSayHelloEnd callback
212    NAPITEST_LOGI("NAPITEST_LOGI NodeISayHelloListener_onSayHelloEndCallback begin\r\n");
213    napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloEndCallback(info2);
214    NAPITEST_LOGI("NAPITEST_LOGI NodeISayHelloListener_onSayHelloEndCallback end\r\n");
215    return;
216}
217
218// 调用register注册的回调
219void NodeISayHello::sayHi(std::string& from, std::string& to, uint32_t& sayType)
220{
221    // 1.打印
222    NAPITEST_LOGI("NAPITEST_LOGI sayHi from = %s\r\n", from.c_str());
223    NAPITEST_LOGI("NAPITEST_LOGI sayHi to = %s\r\n", to.c_str());
224    NAPITEST_LOGI("NAPITEST_LOGI sayHi sayType = %d\r\n", sayType);
225    // 2.调用回调
226    napitest::napitest_interface::NodeISayHello *ptr = new napitest::napitest_interface::NodeISayHello();
227    uint32_t callbackNum = 50;
228    ptr->CallbackfuncCallback(callbackNum);
229    delete ptr;
230    return;
231}
232
233// 普通函数调用,返回str
234std::string funcTest(bool& v)
235{
236    if (v) {
237        return "ret is true";
238    } else {
239        return "ret is false";
240    }
241}
242
243// 1.打印值:from, to 以及枚举enum SayType的值
244// 2. 将回调值(0, "", "recv hello.")的值传回Js层
245void NodeISayHello::sayHelloWithResponse(std::string& from, std::string& to, uint32_t& sayType)
246{
247    // 1.打印
248    NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse from = %s\r\n", from.c_str());
249    NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse to = %s\r\n", to.c_str());
250    NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse sayType = %d\r\n", sayType);
251    // 2.调用promise回调 (0, "", "recv hello.")
252    napitest::napitest_interface::NodeISayHello *p = new  napitest::napitest_interface::NodeISayHello();
253    // 调用工具接口将回调传回工具
254    p->auto_interface_5SetCbValue(0, "", "recv hello.");
255    delete p;
256    return;
257}
258}
259
260```
261
262### 可执行程序使用方法
263
264#### Linux
265
2661.将待转换的.d.ts文件、napi_generator-linux、依赖文件basic.d.ts、 配置文件cfg.json、业务代码文件夹serviceCode(其中serviceCode目录下放置业务代码的.h文件和.cpp文件)放在同级目录下。此处新建generatorCode文件夹,用于存放生成框架代码。整体目录文件如下:
267
268	OpenHarmony@Ubuntu-64:~/service$ ls
269	napi_generator-linux  @ohos.napitest.d.ts  basic.d.ts  generatorCode  cfg.json  serviceCode
270
2712.在终端中进入到之前可执行程序napi_generator-linux所在的目录,并运行napi_generator-linux,命令如下:
272
273	OpenHarmony@Ubuntu-64:~/service$ ./napi_generator-linux -f @ohos.napitest.d.ts -o generatorCode -i false -n int -s cfg.json
274
275其中,参数详情如下:
276
277   -f, 待转换的.d.ts文件,若同时转换多个文件,文件之间用“,”隔开;
278
279  -d, 根据指定路径转换该文件夹中所有.d.ts文件;
280
281  -i, 可选参数,默认false,待转换.d.ts文件中引用非basic.d.ts的ts文件时打开开关;
282
283  -o, 可选参数,默认为当前目录,指定生成框架代码输出路径;
284
285  -n, 可选参数,默认为uint32_t,指定生成框架代码中number类型全部为指定类型;
286
287  -s, 可选参数,默认为不配置业务代码,指定生成框架代码的业务配置文件,用于粘合工具代码和业务代码的配置。
288
289  备注1:-f与-d两个参数只选其中一个参数即可。
290
291  备注2:若.d.ts文件中声明了basic.d.ts文件,将basic.d.ts文件放置在待转换.d.ts文件同一级目录;若除此之外还声明其它.d.ts文件,将此类文件放置在待转换.d.ts文件同级目录。
292
293其中,cfg.json内容如下:
294
295```
296[
297 {
298  "genPath": "/home/kaihong1/napi/myCommitNapiTest/generatorCode",
299  "includeName": "../serviceCode/NodeISayHello.h",
300  "cppName": "../serviceCode/NodeISayHello.cpp",
301  "interfaceName": "funcTest",
302  "serviceCode": "out = napitest::funcTest(v);"
303  "description": "includeName: 引入的业务代码.h文件相对路径, cppName: 引入的业务代码.cpp文件相对路径, interfaceName: ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: funcTest), serviceCode: 在接口中调用业务代码的调用语句。(该属性只做注释使用)"
304 }
305]
306```
307
308cfg.json是一个数组,每一项配置对应一个方法的调用,需要对多少方法进行调用就配置多少项;其中
309
310"genPath": 生成框架代码路径,用户的业务代码相对于该路径配置,如:"/home/kaihong1/napi/myCommitNapiTest/generatorCode"
311
312"includeName": 引入的业务代码.h文件相对路径, 如:"../serviceCode/NodeISayHello.h",
313
314"cppName": 引入的业务代码.cpp文件相对路径,  如:"../serviceCode/NodeISayHello.cpp",
315
316"interfaceName": ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: funcTest),
317
318"serviceCode": 在接口中调用业务代码的调用语句。此处调用的是实现该接口的业务代码, 如:"out = napitest::funcTest(v);",
319
320"description": 仅作为cfg.json文件中描述其它字段含义的属性,用户配置时,可以不用填写这个字段
321
3223.运行成功后会在generatorCode目录下生成框架代码文件,如下所示:
323
324	OpenHarmony@Ubuntu-64:~/linshi/napi_generator_8/examples/ts/generatorCode$ ls
325	binding.gyp  BUILD.gn  napi_gen.log  napitest.cpp  napitest.h  napitest_middle.h napitest_middle.cpp  test.sh  tool_utility.cpp  tool_utility.h
326
327#### Windows
328
3291.将待转换的.d.ts文件、napi_generator-win.exe、 配置文件cfg.json、依赖文件basic.d.ts、业务代码文件夹serviceCode(其中serviceCode目录下放置业务代码的.h文件和.cpp文件)放在同级目录下。此处新建generatorCode文件夹,用于存放生成框架代码。整体目录文件如下:
330
331	E:\demo\napi>dir /B
332	@ohos.napitest.d.ts
333	basic.d.ts
334	napi_generator-win.exe
335	generatorCode
336	cfg.json
337	serviceCode
338
3392.在终端中进入到之前可执行程序napi_generator-win.exe所在的目录,并运行napi_generator-win.exe,命令如下:
340
341	E:\demo\napi>napi_generator-win.exe -f @ohos.napitest.d.ts -o generatorCode -i false -n double -s cfg.json
342
343其中,参数详情如下:
344
345   -f, 待转换的.d.ts文件,若同时转换多个文件,文件之间用“,”隔开;
346
347  -d, 根据指定路径转换该文件夹中所有.d.ts文件;
348
349  -i, 可选参数,默认false,待转换.d.ts文件中引用非basic.d.ts的ts文件时打开开关;
350
351  -o, 可选参数,默认为当前目录,指定生成框架代码输出路径;
352
353   -n, 可选参数,默认为uint32_t,指定生成框架代码中number类型全部为指定类型;
354
355  -s, 可选参数,默认为不配置业务代码,指定生成框架代码的业务配置文件,用于粘合工具代码和业务代码的配置。
356
357  备注1:-f与-d两个参数只选其中一个参数即可。
358
359  备注2:若.d.ts文件中声明了basic.d.ts文件,将basic.d.ts文件放置在待转换.d.ts文件同一级目录;若除此之外还声明其它.d.ts文件,将此类文件放置在待转换.d.ts文件同级目录。
360
361其中,cfg.json内容如下:
362
363```
364[
365 {
366  "genPath": "E:\\napi_aboutTest\\testcase_napi_intellijPlugin\\generatorCode",
367  "includeName": "../serviceCode/NodeISayHello.h",
368  "cppName": "../serviceCode/NodeISayHello.cpp",
369  "interfaceName": "funcTest",
370  "serviceCode": "out = napitest::funcTest(v);"
371  "description": "includeName: 引入的业务代码.h文件相对路径, cppName: 引入的业务代码.cpp文件相对路径, interfaceName: ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: funcTest), serviceCode: 在接口中调用业务代码的调用语句。(该属性只做注释使用)"
372 }
373]
374```
375
376cfg.json是一个数组,每一项配置对应一个方法的调用,需要对多少方法进行调用就配置多少项;其中
377
378"genPath": 生成框架代码路径,用户的业务代码相对于该路径配置,如:"E:\\napi_aboutTest\\testcase_napi_intellijPlugin\\generatorCode"
379
380"includeName": 引入的业务代码.h文件相对路径, 如:"../serviceCode/NodeISayHello.h",
381
382"cppName": 引入的业务代码.cpp文件相对路径,  如:"../serviceCode/NodeISayHello.cpp",
383
384"interfaceName": ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: funcTest),
385
386"serviceCode": 在接口中调用业务代码的调用语句。此处调用的是实现该接口的业务代码, 如:"out = napitest::funcTest(v);",
387
388"description": 仅作为cfg.json文件中描述其它字段含义的属性,用户配置时,可以不用填写这个字段
389
3903.运行成功后会在generatorCode目录下生成框架代码文件,如下所示:
391
392	E:\demo\napi\generatorCode>dir /B
393	binding.gyp
394	BUILD.gn
395	napitest.cpp
396	napitest.h
397	napitest_middle.h
398	napitest_middle.cpp
399	napi_gen.log
400	test.sh
401	tool_utility.cpp
402	tool_utility.h
403
404#### Mac
405
406方法步骤参考windows、Linux的使用方法。
407
408### 不配置cfg.json文件生成框架代码
409
410若用户想手动配置业务代码,可不配置cfg.json文件生成框架代码之后手动增加业务代码,不配置cfg.json文件生成框架代码说明如下:
411
412[不配置cfg.json生成框架代码说明](https://gitee.com/openharmony/napi_generator/blob/master/src/cli/dts2cpp/docs/usage/ADD_SERVICECODE_INSTRUCTION.md)
413
414### VS Code插件使用方法
415
416具体的插件使用步骤,可以左键单击以下链接了解:
417
418[VS插件使用说明](https://gitee.com/openharmony/napi_generator/blob/master/src/vscode_plugin/dts2cpp/napi_vs_plugin/docs/usage/INSTRUCTION_ZH.md)
419
420### DevEco Studio上使用的IntelliJ插件使用方法
421
422具体的插件使用步骤,可以左键单击以下链接了解:
423
424[DevEco Studio上使用的IntelliJ插件使用说明](https://gitee.com/openharmony/napi_generator/blob/master/src/intellij_plugin/dts2cpp/napi_IntelliJ_plugin/docs/usage/INSTRUCTION_ZH.md)
425
426## 集成测试
427NAPI框架代码生成后,系统框架开发者进行二次开发后,即可集成到OpenHarmony编译系统,生成对应的库文件,供应用开发者调用接口。工具集成测试的具体操作步骤可以左键单击以下链接了解:
428
429  [工具集成测试](https://gitee.com/openharmony/napi_generator/blob/master/src/cli/dts2cpp/docs/usage/INTEGRATION_TESTING_ZH.md)
430
431