• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# NAPI框架生成代码集成到OpenHarmony的方法
2
3## 场景说明
4
5为了实现工具生成的接口被其它子系统或者应用调用,需将生成的代码编译集成到OpenHarmony系统中,使其生成动态库,供OpenHarmony应用层调用。
6本文介绍如何将工具生成的源码利用OpenHarmony编译系统生成动态库供应用层调用,主要是有以下两种方式,分别为增加ohos.build文件方式和增加bundle.json文件方式。
7
8## 4.0 版本
9
10### 建立模块位置
11
12模块目录理论上可在OpenHarmony工程的任一位置,假设OpenHarmony代码库的目录为OHOS_SRC,在OHOS_SRC/foundation目录下,建测试模块目录:napitest。napitest目录结构如下:
13
14    napitest
15    |-- generatorCode // 工具代码部分
16    |-- |-- binding.gyp
17    |-- |-- BUILD.gn
18    |-- |-- bundle.json
19    |-- |-- napitest.cpp
20    |-- |-- napitest.h
21    |-- |-- napitest_middle.h
22    |-- |-- napitest_middle.cpp
23    |-- |-- test.sh
24    |-- |-- tool_utility.cpp
25    |-- |-- tool_utility.h
26    |-- |-- napi_gen.log
27    |-- serviceCode  // 放置业务代码部分
28    |-- |-- NodeISayHello.h
29    |-- |-- NodeISayHello.cpp
30
31其中generatorCode为工具生成的代码,serviceCode 为用户配置的业务代码, bundle.json 为新增的编译配置文件。
32
33### 编译修改点
34
35#### 修改bundle.json文件
36
37其中destPath选项中的"//foundation/napitest/generatorCode"指的是napitest目录,":napitest"指的是上面BUILD.gn中的目标ohos_shared_library("napitest")。
38
39```
40{
41  "name": "@ohos/napitest",
42  "description": "napitest provides atomic capabilities",
43  "version": "4.0",
44  "license": "Apache License 2.0",
45  "publishAs": "code-segment",
46  "segment": {
47    "destPath": "foundation/napitest/generatorCode"
48  },
49  "dirs": {},
50  "scripts": {},
51  "component": {
52    "name": "napitest",
53    "subsystem": "napitest",
54    "features": [],
55    "adapted_system_type": [
56      "standard"
57    ],
58    "rom": "10000KB",
59    "ram": "10000KB",
60    "deps": {
61      "components": [
62        "ace_napi",
63        "ipc_core",
64        "libhilog"
65      ],
66      "third_party": [
67        "node"
68      ]
69    },
70    "build": {
71      "sub_component": [
72        "//foundation/napitest/generatorCode:napitest"
73      ],
74      "inner_kits": [
75        {
76          "header": {
77            "header_base": "//foundation/napitest/generatorCode",
78            "header_files": [
79              "tool_utility.h",
80              "napitest.h",
81              "napitest_middle.h"
82            ]
83          },
84          "name": "//foundation/napitest/generatorCode:napitest"
85        }
86      ]
87    }
88  }
89}
90```
91
92#### 增加子系统
93
94在源码/build/subsystem_config.json中增加子系统选项。如下所示:
95
96```
97"napitest": {
98    "path": "foundation/napitest/generatorCode",
99    "name": "napitest"
100  }
101```
102
103### 添加功能模块
104
105在产品配置中添加上述子系统的功能模块,编译到产品产出文件中,例如在源码vendor/hihope/rk3568/config.json中增加part选项,其中the first napitest就是BUILD.gn文件中的subsystem_name,第二个napitest就是BUILD.gn文件中的part_name。
106
107```
108{
109      "subsystem": "napitest",
110      "components": [
111        {
112          "component": "napitest",
113          "features": []
114        }
115      ]
116}
117```
118
119### 编译验证
120
121编译成功后,就会在 /out/产品名/packages/phone/system/lib/module/ 生成libnapitest.z.so,如下所示:
122
123    /out/rk3568/packages/phone/system/lib/module
124
125### 备注
126
127若自动配置业务代码不能满足业务场景,用户可以手动配置业务代码,以下为用户手动配置业务代码并集成到OpenHarmony上的方法:
128
129[4.0版本手动配置业务代码集成方法](https://gitee.com/openharmony/napi_generator/blob/master/src/cli/dts2cpp/docs/usage/ENSEMBLE_METHOD_4.0CFGCODE.md)
130
131## 3.2 版本
132
133### 建立模块位置
134
135模块目录理论上可在OpenHarmony工程的任一位置,假设OpenHarmony代码库的目录为OHOS_SRC,在OHOS_SRC/foundation目录下,建测试模块目录:napitest。napitest目录结构如下:
136
137    napitest
138    |-- binding.gyp
139    |-- BUILD.gn
140    |-- bundle.json
141    |-- napitest.cpp
142    |-- napitest.h
143    |-- napitest_middle.h
144    |-- napitest_middle.cpp
145    |-- test.sh
146    |-- tool_utility.cpp
147    |-- tool_utility.h
148
149其中bundle.json为新建的编译配置文件,其它为工具生成的代码。
150
151### 编译修改点
152
153#### 修改bundle.json文件
154
155其中destPath选项中的"//foundation/napitest"指的是napitest目录,":napitest"指的是上面BUILD.gn中的目标ohos_shared_library("napitest")。
156
157```
158{
159  "name": "@ohos/napitest",
160  "description": "napitest provides atomic capabilities",
161  "version": "3.2",
162  "license": "Apache License 2.0",
163  "publishAs": "code-segment",
164  "segment": {
165    "destPath": "foundation/napitest"
166  },
167  "dirs": {},
168  "scripts": {},
169  "component": {
170    "name": "napitest",
171    "subsystem": "napitest",
172    "features": [],
173    "adapted_system_type": [
174      "standard"
175    ],
176    "rom": "10000KB",
177    "ram": "10000KB",
178    "deps": {
179      "components": [
180        "ace_napi",
181        "ipc_core",
182        "libhilog"
183      ],
184      "third_party": [
185        "node"
186      ]
187    },
188    "build": {
189      "sub_component": [
190        "//foundation/napitest:napitest"
191      ],
192      "inner_kits": [
193        {
194          "header": {
195            "header_base": "//foundation/napitest",
196            "header_files": [
197              "tool_utility.h",
198              "napitest.h",
199              "napitest_middle.h"
200            ]
201          },
202          "name": "//foundation/napitest:napitest"
203        }
204      ]
205    }
206  }
207}
208```
209
210#### 修改napitest.cpp文件
211
212为方便调试,在napitest.cpp文件中增加业务代码。以修改napitest.cpp文件为例,在以下方法中增加业务代码,
213
214在sayHello方法中增加注册的object回调方法的调用:
215
216```
217...
218// 业务代码调用 onSayHelloStart callback
219napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloStartCallback(info1);
220// 业务代码调用 onSayHelloEnd callback
221napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloEndCallback(info2);
222...
223```
224
225在sayHi方法中增加register注册的回调方法的调用:
226
227```
228...
229napitest::napitest_interface::NodeISayHello *ptr = new napitest::napitest_interface::NodeISayHello();
230uint32_t callbackNum = 50;
231ptr->CallbackfuncCallback(callbackNum);
232delete ptr;
233...
234```
235
236在sayHelloWithResponse方法中增加Promise回调方法的调用:
237
238```
239...
240out.errMsg = "";
241out.response = "rec hello.";
242out.result = 0;
243...
244```
245
246在funcTest方法中增加普通函数的业务逻辑:
247
248```
249...
250if (v) {
251    out = "ret is true";
252} else {
253    out = "ret is false";
254}
255...
256```
257
258增加业务代码之后的文件如下所示:
259
260```
261#include "napitest.h"
262#include "napitest_middle.h"
263#include "hilog/log.h"
264static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0XD002E00, "NAPITESTNAPILayer"};
265#define NAPITEST_LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \
266    	"%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__)
267
268namespace napitest {
269namespace napitest_interface {
270NodeISayHelloListener NodeISayHello::listener_ = {};
271bool NodeISayHello::addSayHelloListener(NodeISayHelloListener& listener)
272{
273    NodeISayHello::listener_ = listener;
274    return true;
275}
276
277bool NodeISayHello::removeSayHelloListener(NodeISayHelloListener& listener)
278{
279    return true;
280}
281
282bool NodeISayHello::registerCallbackfunc()
283{
284    return true;
285}
286
287// 供业务调用的回调接口
288void NodeISayHello::CallbackfuncCallback(NUMBER_TYPE_2& wid)
289{
290    std::string eventName = "Callbackfunc";
291    NodeISayHello_middle *ptr = new NodeISayHello_middle();
292    ptr->CallbackfuncCallbackMiddle(eventName,  wid);
293    delete ptr;
294}
295
296bool NodeISayHello::unRegisterCallbackfunc()
297{
298    return true;
299}
300
301bool NodeISayHello::sayHello(std::string& from, std::string& to, NUMBER_TYPE_9& sayType)
302{
303    NAPITEST_LOGI("NAPITEST_LOGI sayHello from = %s\r\n", from.c_str());
304    NAPITEST_LOGI("NAPITEST_LOGI sayHello to = %s\r\n", to.c_str());
305    NAPITEST_LOGI("NAPITEST_LOGI sayHello sayType = %d\r\n", sayType);
306    SayInfo info1;
307    info1.from = "js1";
308    uint32_t a = 992;
309    info1.fromId.emplace(a);
310    uint32_t b = 1014;
311    info1.toId.emplace(b);
312    info1.to = "native1";
313    info1.content = "hello1";
314    info1.saidTime = "123456789";
315    info1.isEnd = false;
316    SayInfo info2;
317    info2.from = "native";
318    uint32_t c = 101;
319    info2.fromId.emplace(c);
320    uint32_t d = 99;
321    info2.toId.emplace(d);
322    info2.to = "js";
323    info2.content = "hello";
324    info2.saidTime = "987654321";
325    info2.isEnd = true;
326    // 业务代码调用 onSayHelloStart callback
327    listener_.NodeISayHelloListener_onSayHelloStartCallback(info1);
328    // 业务代码调用 onSayHelloEnd callback
329    listener_.NodeISayHelloListener_onSayHelloEndCallback(info2);
330    return true;
331}
332
333bool NodeISayHello::sayHi(std::string& from, std::string& to, NUMBER_TYPE_10& sayType)
334{
335    NAPITEST_LOGI("NAPITEST_LOGI sayHi from = %s\r\n", from.c_str());
336    NAPITEST_LOGI("NAPITEST_LOGI sayHi to = %s\r\n", to.c_str());
337    NAPITEST_LOGI("NAPITEST_LOGI sayHi sayType = %d\r\n", sayType);
338    NodeISayHello *ptr = new NodeISayHello();
339    uint32_t callbackNum = 50;
340    ptr->CallbackfuncCallback(callbackNum);
341    delete ptr;
342    return true;
343}
344
345bool NodeISayHello::sayHelloWithResponse(std::string& from, std::string& to, NUMBER_TYPE_11& sayType,
346    uint32_t& outErrCode, AUTO_INTERFACE_5& out)
347{
348    NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse from = %s\r\n", from.c_str());
349    NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse to = %s\r\n", to.c_str());
350    NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse sayType = %d\r\n", sayType);
351    out.errMsg = "";
352    out.response = "rec hello.";
353    out.result = 0;
354    return true;
355}
356
357AUTO_INTERFACE_5 NodeISayHello::auto_interface_5OutRes = {};
358void NodeISayHello::auto_interface_5SetCbValue(NUMBER_TYPE_6 result, std::string errMsg, std::string response)
359{
360    NodeISayHello::auto_interface_5OutRes.result = result;
361    NodeISayHello::auto_interface_5OutRes.errMsg = errMsg;
362    NodeISayHello::auto_interface_5OutRes.response = response;
363    return;
364}
365
366bool NodeISayHelloListener::onSayHelloStart()
367{
368    return true;
369}
370
371// 供业务调用的回调接口
372void NodeISayHelloListener::NodeISayHelloListener_onSayHelloStartCallback(SayInfo& info)
373{
374    std::string eventName = "NodeISayHelloListener_onSayHelloStart";
375    NodeISayHelloListener_middle *ptr = new NodeISayHelloListener_middle();
376    ptr->NodeISayHelloListener_onSayHelloStartCallbackMiddle(eventName,  info);
377    delete ptr;
378}
379
380bool NodeISayHelloListener::onSayHelloEnd()
381{
382    return true;
383}
384
385// 供业务调用的回调接口
386void NodeISayHelloListener::NodeISayHelloListener_onSayHelloEndCallback(SayInfo& info)
387{
388    std::string eventName = "NodeISayHelloListener_onSayHelloEnd";
389    NodeISayHelloListener_middle *ptr = new NodeISayHelloListener_middle();
390    ptr->NodeISayHelloListener_onSayHelloEndCallbackMiddle(eventName,  info);
391    delete ptr;
392}
393
394bool funcTest(bool& v, std::string& out)
395{
396    if (v) {
397        out = "ret is true";
398    } else {
399        out = "ret is false";
400    }
401    return true;
402}
403}
404}
405
406```
407
408#### 增加子系统
409
410在源码/build/subsystem_config.json中增加子系统选项。如下所示:
411
412```
413"napitest": {
414    "path": "foundation/napitest",
415    "name": "napitest"
416  }
417```
418
419### 添加功能模块
420
421在产品配置中添加上述子系统的功能模块,编译到产品产出文件中,例如在源码vendor/hihope/rk3568/config.json中增加part选项,其中the first napitest就是BUILD.gn文件中的subsystem_name,第二个napitest就是BUILD.gn文件中的part_name。
422
423```
424{
425      "subsystem": "napitest",
426      "components": [
427        {
428          "component": "napitest",
429          "features": []
430        }
431      ]
432}
433```
434
435### 编译验证
436
437编译成功后,就会在 /out/产品名/packages/phone/system/lib/module/ 生成libnapitest.z.so,如下所示:
438
439    /out/rk3568/packages/phone/system/lib/module
440
441## 3.1 版本
442
443[3.1版本集成方法](https://gitee.com/openharmony/napi_generator/blob/master/src/cli/dts2cpp/docs/usage/ENSEMBLE_METHOD_3.1VERSION.md)
444
445## 总结
446
4473.1版本两种集成方式使用场景说明:
448
449ohos.build方式集成:适合3.0前版本使用。
450
451bundle.json方式集成:兼容ohos.build方式,但3.1及以后版本建议使用此种方式集成。
452
4533.2版本适合使用bundle.json方式集成。
454
4554.0版本适合使用bundle.json方式集成。
456
457