1# 集成到OpenHarmony 3.1 Release的方法 2 3## 场景说明 4 5为了实现工具生成的接口被其它子系统或者应用调用,需将生成的代码编译集成到OpenHarmony系统中,使其生成动态库,供OpenHarmony应用层调用。 6本文介绍如何将工具生成的源码利用OpenHarmony编译系统生成动态库供应用层调用,集成到OpenHarmony 3.1 Release主要是有以下两种方式,分别为增加ohos.build文件方式和增加bundle.json文件方式。 7 8## 3.1 版本 9 10### bundle.json方式集成 11 12#### 建立模块位置 13 14模块目录理论上可在OpenHarmony工程的任一位置,假设OpenHarmony代码库的目录为OHOS_SRC,在OHOS_SRC/foundation目录下,建测试模块目录:napitest。napitest目录结构如下: 15 16 napitest 17 |-- binding.gyp 18 |-- BUILD.gn 19 |-- bundle.json 20 |-- napitest.cpp 21 |-- napitest.h 22 |-- napitest_middle.h 23 |-- napitest_middle.cpp 24 |-- test.sh 25 |-- tool_utility.cpp 26 |-- tool_utility.h 27 28其中bundle.json为新增的编译配置文件,其它为工具生成的代码。 29 30#### 编译修改点 31 32##### 修改BUILD.gn文件 33 34将deps中"//foundation/arkui/napi:ace_napi"的修改为"//foundation/ace/napi:ace_napi",修改后的BUILD.gn文件内容如下所示: 35 36``` 37import("//build/ohos.gni") 38 39ohos_shared_library("napitest") 40{ 41 sources = [ 42 "napitest_middle.cpp", 43 "../serviceCode/NodeISayHello.cpp", # 将业务代码编译进去 44 "napitest.cpp", 45 "tool_utility.cpp", 46 ] 47 include_dirs = [ 48 ".", 49 "//third_party/node/src", 50 ] 51 deps=[ 52 "//foundation/ace/napi:ace_napi", 53 "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", 54 ] 55 remove_configs = [ "//build/config/compiler:no_rtti" ] 56 cflags=[ 57 ] 58 cflags_cc=[ 59 "-frtti", 60 ] 61 ldflags = [ 62 ] 63 64 relative_install_dir = "module" 65 part_name = "napitest" 66 subsystem_name = "napitest" 67} 68``` 69 70若用户需要修改子系统和部件名称,则根据自身需求修改BUILD.gn文件和bundle.json文件中子系统与部件名称即可。 71 72##### 修改bundle.json文件 73 74其中destPath选项中的"//foundation/napitest"指的是napitest目录,":napitest"指的是上面BUILD.gn中的目标ohos_shared_library("napitest")。 75 76``` 77{ 78 "name": "@ohos/napitest", 79 "description": "napitest provides atomic capabilities", 80 "version": "3.1", 81 "license": "Apache License 2.0", 82 "publishAs": "code-segment", 83 "segment": { 84 "destPath": "foundation/napitest" 85 }, 86 "dirs": {}, 87 "scripts": {}, 88 "component": { 89 "name": "napitest", 90 "subsystem": "napitest", 91 "features": [], 92 "adapted_system_type": [ 93 "standard" 94 ], 95 "rom": "10000KB", 96 "ram": "10000KB", 97 "deps": { 98 "components": [ 99 "ace_napi", 100 "ipc_core", 101 "libhilog" 102 ], 103 "third_party": [ 104 "node" 105 ] 106 }, 107 "build": { 108 "sub_component": [ 109 "//foundation/napitest:napitest" 110 ], 111 "inner_kits": [ 112 { 113 "header": { 114 "header_base": "//foundation/napitest", 115 "header_files": [ 116 "tool_utility.h", 117 "napitest.h", 118 "napitest_middle.h" 119 ] 120 }, 121 "name": "//foundation/napitest:napitest" 122 } 123 ] 124 } 125 } 126} 127``` 128 129##### 修改napitest.cpp文件 130 131为方便调试,在napitest.cpp文件中增加业务代码。以修改napitest.cpp文件为例,在以下方法中增加业务代码, 132 133在sayHello方法中增加注册的object回调方法的调用: 134 135``` 136... 137// 业务代码调用 onSayHelloStart callback 138napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloStartCallback(info1); 139// 业务代码调用 onSayHelloEnd callback 140napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloEndCallback(info2); 141... 142``` 143 144在sayHi方法中增加register注册的回调方法的调用: 145 146``` 147... 148napitest::napitest_interface::NodeISayHello *ptr = new napitest::napitest_interface::NodeISayHello(); 149uint32_t callbackNum = 50; 150ptr->CallbackfuncCallback(callbackNum); 151delete ptr; 152... 153``` 154 155在sayHelloWithResponse方法中增加Promise回调方法的调用: 156 157``` 158... 159out.errMsg = ""; 160out.response = "rec hello."; 161out.result = 0; 162... 163``` 164 165在funcTest方法中增加普通函数的业务逻辑: 166 167``` 168... 169if (v) { 170 out = "ret is true"; 171} else { 172 out = "ret is false"; 173} 174... 175``` 176 177增加业务代码之后的文件如下所示: 178 179``` 180#include "napitest.h" 181#include "napitest_middle.h" 182#include "hilog/log.h" 183static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0XD002E00, "NAPITESTNAPILayer"}; 184#define NAPITEST_LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \ 185 "%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__) 186 187namespace napitest { 188namespace napitest_interface { 189NodeISayHelloListener NodeISayHello::listener_ = {}; 190bool NodeISayHello::addSayHelloListener(NodeISayHelloListener& listener) 191{ 192 NodeISayHello::listener_ = listener; 193 return true; 194} 195 196bool NodeISayHello::removeSayHelloListener(NodeISayHelloListener& listener) 197{ 198 return true; 199} 200 201bool NodeISayHello::registerCallbackfunc() 202{ 203 return true; 204} 205 206// 供业务调用的回调接口 207void NodeISayHello::CallbackfuncCallback(NUMBER_TYPE_2& wid) 208{ 209 std::string eventName = "Callbackfunc"; 210 NodeISayHello_middle *ptr = new NodeISayHello_middle(); 211 ptr->CallbackfuncCallbackMiddle(eventName, wid); 212 delete ptr; 213} 214 215bool NodeISayHello::unRegisterCallbackfunc() 216{ 217 return true; 218} 219 220bool NodeISayHello::sayHello(std::string& from, std::string& to, NUMBER_TYPE_9& sayType) 221{ 222 NAPITEST_LOGI("NAPITEST_LOGI sayHello from = %s\r\n", from.c_str()); 223 NAPITEST_LOGI("NAPITEST_LOGI sayHello to = %s\r\n", to.c_str()); 224 NAPITEST_LOGI("NAPITEST_LOGI sayHello sayType = %d\r\n", sayType); 225 SayInfo info1; 226 info1.from = "js1"; 227 uint32_t a = 992; 228 info1.fromId.emplace(a); 229 uint32_t b = 1014; 230 info1.toId.emplace(b); 231 info1.to = "native1"; 232 info1.content = "hello1"; 233 info1.saidTime = "123456789"; 234 info1.isEnd = false; 235 SayInfo info2; 236 info2.from = "native"; 237 uint32_t c = 101; 238 info2.fromId.emplace(c); 239 uint32_t d = 99; 240 info2.toId.emplace(d); 241 info2.to = "js"; 242 info2.content = "hello"; 243 info2.saidTime = "987654321"; 244 info2.isEnd = true; 245 // 业务代码调用 onSayHelloStart callback 246 listener_.NodeISayHelloListener_onSayHelloStartCallback(info1); 247 // 业务代码调用 onSayHelloEnd callback 248 listener_.NodeISayHelloListener_onSayHelloEndCallback(info2); 249 return true; 250} 251 252bool NodeISayHello::sayHi(std::string& from, std::string& to, NUMBER_TYPE_10& sayType) 253{ 254 NAPITEST_LOGI("NAPITEST_LOGI sayHi from = %s\r\n", from.c_str()); 255 NAPITEST_LOGI("NAPITEST_LOGI sayHi to = %s\r\n", to.c_str()); 256 NAPITEST_LOGI("NAPITEST_LOGI sayHi sayType = %d\r\n", sayType); 257 NodeISayHello *ptr = new NodeISayHello(); 258 uint32_t callbackNum = 50; 259 ptr->CallbackfuncCallback(callbackNum); 260 delete ptr; 261 return true; 262} 263 264bool NodeISayHello::sayHelloWithResponse(std::string& from, std::string& to, NUMBER_TYPE_11& sayType, 265 uint32_t& outErrCode, AUTO_INTERFACE_5& out) 266{ 267 NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse from = %s\r\n", from.c_str()); 268 NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse to = %s\r\n", to.c_str()); 269 NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse sayType = %d\r\n", sayType); 270 out.errMsg = ""; 271 out.response = "rec hello."; 272 out.result = 0; 273 return true; 274} 275 276AUTO_INTERFACE_5 NodeISayHello::auto_interface_5OutRes = {}; 277void NodeISayHello::auto_interface_5SetCbValue(NUMBER_TYPE_6 result, std::string errMsg, std::string response) 278{ 279 NodeISayHello::auto_interface_5OutRes.result = result; 280 NodeISayHello::auto_interface_5OutRes.errMsg = errMsg; 281 NodeISayHello::auto_interface_5OutRes.response = response; 282 return; 283} 284 285bool NodeISayHelloListener::onSayHelloStart() 286{ 287 return true; 288} 289 290// 供业务调用的回调接口 291void NodeISayHelloListener::NodeISayHelloListener_onSayHelloStartCallback(SayInfo& info) 292{ 293 std::string eventName = "NodeISayHelloListener_onSayHelloStart"; 294 NodeISayHelloListener_middle *ptr = new NodeISayHelloListener_middle(); 295 ptr->NodeISayHelloListener_onSayHelloStartCallbackMiddle(eventName, info); 296 delete ptr; 297} 298 299bool NodeISayHelloListener::onSayHelloEnd() 300{ 301 return true; 302} 303 304// 供业务调用的回调接口 305void NodeISayHelloListener::NodeISayHelloListener_onSayHelloEndCallback(SayInfo& info) 306{ 307 std::string eventName = "NodeISayHelloListener_onSayHelloEnd"; 308 NodeISayHelloListener_middle *ptr = new NodeISayHelloListener_middle(); 309 ptr->NodeISayHelloListener_onSayHelloEndCallbackMiddle(eventName, info); 310 delete ptr; 311} 312 313bool funcTest(bool& v, std::string& out) 314{ 315 if (v) { 316 out = "ret is true"; 317 } else { 318 out = "ret is false"; 319 } 320 return true; 321} 322} 323} 324 325``` 326 327##### 增加子系统 328 329在源码/build/subsystem_config.json中增加子系统选项。如下所示: 330 331``` 332"napitest": { 333 "project": "hmf/napitest", 334 "path": "foundation/napitest", 335 "name": "napitest", 336 "dir": "foundation" 337 } 338``` 339 340#### 添加功能模块 341 342在产品配置中添加上述子系统的功能模块,编译到产品产出文件中,例如在源码/productdefine/common/products/rk3566.json中增加part选项,其中the first napitest就是BUILD.gn文件中的subsystem_name,第二个napitest就是BUILD.gn文件中的part_name。 343 344 "napitest:napitest":{} 345 346#### 编译验证 347 348编译成功后,就会在 /out/产品名/packages/phone/system/lib/module/ 生成libnapitest.z.so,如下所示: 349 350 /out/ohos-arm-release/packages/phone/system/lib/module 351 352### ohos.build方式集成 353 354#### 建立模块位置 355 356模块目录理论上可在OpenHarmony工程的任一位置,假设OpenHarmony代码库的目录为OHOS_SRC,在OHOS_SRC/foundation目录下,建测试模块目录:napitest。napitest目录结构如下: 357 358 napitest 359 |-- binding.gyp 360 |-- BUILD.gn 361 |-- ohos.build 362 |-- napitest.cpp 363 |-- napitest.h 364 |-- napitest_middle.h 365 |-- napitest_middle.cpp 366 |-- test.sh 367 |-- tool_utility.cpp 368 |-- tool_utility.h 369 370其中ohos.build为新增的编译配置文件,其它为工具生成的代码。 371 372#### 编译修改点 373 374##### 修改BUILD.gn文件 375 376将deps中"//foundation/arkui/napi:ace_napi"的修改为"//foundation/ace/napi:ace_napi",修改后的BUILD.gn文件内容如下所示: 377 378``` 379import("//build/ohos.gni") 380 381ohos_shared_library("napitest") 382{ 383 sources = [ 384 "napitest_middle.cpp", 385 "../serviceCode/NodeISayHello.cpp", # 将业务代码编译进去 386 "napitest.cpp", 387 "tool_utility.cpp", 388 ] 389 include_dirs = [ 390 ".", 391 "//third_party/node/src", 392 ] 393 deps=[ 394 "//foundation/ace/napi:ace_napi", 395 "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", 396 ] 397 remove_configs = [ "//build/config/compiler:no_rtti" ] 398 cflags=[ 399 ] 400 cflags_cc=[ 401 "-frtti", 402 ] 403 ldflags = [ 404 ] 405 406 relative_install_dir = "module" 407 part_name = "napitest" 408 subsystem_name = "napitest" 409} 410``` 411 412若用户需要修改子系统和部件名称,则根据自身需求修改BUILD.gn文件和ohos.build文件中子系统与部件名称即可。 413 414##### 修改ohos.build文件 415 416其中module_list选项中的"//foundation/napitest"指的是napitest目录,":napitest"指的是上面BUILD.gn中的目标ohos_shared_library("napitest")。 417 418``` 419{ 420 "subsystem": "napitest", 421 "parts": { 422 "napitest": { 423 "module_list": [ 424 "//foundation/napitest:napitest" 425 ], 426 "test_list": [] 427 } 428 } 429} 430``` 431 432##### 修改napitest.cpp文件 433 434为方便调试,在napitest.cpp文件中增加业务代码。以修改napitest.cpp文件为例,在以下方法中增加业务代码, 435 436在sayHello方法中增加注册的object回调方法的调用: 437 438``` 439... 440// 业务代码调用 onSayHelloStart callback 441napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloStartCallback(info1); 442// 业务代码调用 onSayHelloEnd callback 443napitest::napitest_interface::NodeISayHello::listener_.NodeISayHelloListener_onSayHelloEndCallback(info2); 444... 445``` 446 447在sayHi方法中增加register注册的回调方法的调用: 448 449``` 450... 451napitest::napitest_interface::NodeISayHello *ptr = new napitest::napitest_interface::NodeISayHello(); 452uint32_t callbackNum = 50; 453ptr->CallbackfuncCallback(callbackNum); 454delete ptr; 455... 456``` 457 458在sayHelloWithResponse方法中增加Promise回调方法的调用: 459 460``` 461... 462out.errMsg = ""; 463out.response = "rec hello."; 464out.result = 0; 465... 466``` 467 468在funcTest方法中增加普通函数的业务逻辑: 469 470``` 471... 472if (v) { 473 out = "ret is true"; 474} else { 475 out = "ret is false"; 476} 477... 478``` 479 480增加业务代码之后的文件如下所示: 481 482``` 483#include "napitest.h" 484#include "napitest_middle.h" 485#include "hilog/log.h" 486static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0XD002E00, "NAPITESTNAPILayer"}; 487#define NAPITEST_LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \ 488 "%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__) 489 490namespace napitest { 491namespace napitest_interface { 492NodeISayHelloListener NodeISayHello::listener_ = {}; 493bool NodeISayHello::addSayHelloListener(NodeISayHelloListener& listener) 494{ 495 NodeISayHello::listener_ = listener; 496 return true; 497} 498 499bool NodeISayHello::removeSayHelloListener(NodeISayHelloListener& listener) 500{ 501 return true; 502} 503 504bool NodeISayHello::registerCallbackfunc() 505{ 506 return true; 507} 508 509// 供业务调用的回调接口 510void NodeISayHello::CallbackfuncCallback(NUMBER_TYPE_2& wid) 511{ 512 std::string eventName = "Callbackfunc"; 513 NodeISayHello_middle *ptr = new NodeISayHello_middle(); 514 ptr->CallbackfuncCallbackMiddle(eventName, wid); 515 delete ptr; 516} 517 518bool NodeISayHello::unRegisterCallbackfunc() 519{ 520 return true; 521} 522 523bool NodeISayHello::sayHello(std::string& from, std::string& to, NUMBER_TYPE_9& sayType) 524{ 525 NAPITEST_LOGI("NAPITEST_LOGI sayHello from = %s\r\n", from.c_str()); 526 NAPITEST_LOGI("NAPITEST_LOGI sayHello to = %s\r\n", to.c_str()); 527 NAPITEST_LOGI("NAPITEST_LOGI sayHello sayType = %d\r\n", sayType); 528 SayInfo info1; 529 info1.from = "js1"; 530 uint32_t a = 992; 531 info1.fromId.emplace(a); 532 uint32_t b = 1014; 533 info1.toId.emplace(b); 534 info1.to = "native1"; 535 info1.content = "hello1"; 536 info1.saidTime = "123456789"; 537 info1.isEnd = false; 538 SayInfo info2; 539 info2.from = "native"; 540 uint32_t c = 101; 541 info2.fromId.emplace(c); 542 uint32_t d = 99; 543 info2.toId.emplace(d); 544 info2.to = "js"; 545 info2.content = "hello"; 546 info2.saidTime = "987654321"; 547 info2.isEnd = true; 548 // 业务代码调用 onSayHelloStart callback 549 listener_.NodeISayHelloListener_onSayHelloStartCallback(info1); 550 // 业务代码调用 onSayHelloEnd callback 551 listener_.NodeISayHelloListener_onSayHelloEndCallback(info2); 552 return true; 553} 554 555bool NodeISayHello::sayHi(std::string& from, std::string& to, NUMBER_TYPE_10& sayType) 556{ 557 NAPITEST_LOGI("NAPITEST_LOGI sayHi from = %s\r\n", from.c_str()); 558 NAPITEST_LOGI("NAPITEST_LOGI sayHi to = %s\r\n", to.c_str()); 559 NAPITEST_LOGI("NAPITEST_LOGI sayHi sayType = %d\r\n", sayType); 560 NodeISayHello *ptr = new NodeISayHello(); 561 uint32_t callbackNum = 50; 562 ptr->CallbackfuncCallback(callbackNum); 563 delete ptr; 564 return true; 565} 566 567bool NodeISayHello::sayHelloWithResponse(std::string& from, std::string& to, NUMBER_TYPE_11& sayType, 568 uint32_t& outErrCode, AUTO_INTERFACE_5& out) 569{ 570 NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse from = %s\r\n", from.c_str()); 571 NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse to = %s\r\n", to.c_str()); 572 NAPITEST_LOGI("NAPITEST_LOGI sayHelloWithResponse sayType = %d\r\n", sayType); 573 out.errMsg = ""; 574 out.response = "rec hello."; 575 out.result = 0; 576 return true; 577} 578 579AUTO_INTERFACE_5 NodeISayHello::auto_interface_5OutRes = {}; 580void NodeISayHello::auto_interface_5SetCbValue(NUMBER_TYPE_6 result, std::string errMsg, std::string response) 581{ 582 NodeISayHello::auto_interface_5OutRes.result = result; 583 NodeISayHello::auto_interface_5OutRes.errMsg = errMsg; 584 NodeISayHello::auto_interface_5OutRes.response = response; 585 return; 586} 587 588bool NodeISayHelloListener::onSayHelloStart() 589{ 590 return true; 591} 592 593// 供业务调用的回调接口 594void NodeISayHelloListener::NodeISayHelloListener_onSayHelloStartCallback(SayInfo& info) 595{ 596 std::string eventName = "NodeISayHelloListener_onSayHelloStart"; 597 NodeISayHelloListener_middle *ptr = new NodeISayHelloListener_middle(); 598 ptr->NodeISayHelloListener_onSayHelloStartCallbackMiddle(eventName, info); 599 delete ptr; 600} 601 602bool NodeISayHelloListener::onSayHelloEnd() 603{ 604 return true; 605} 606 607// 供业务调用的回调接口 608void NodeISayHelloListener::NodeISayHelloListener_onSayHelloEndCallback(SayInfo& info) 609{ 610 std::string eventName = "NodeISayHelloListener_onSayHelloEnd"; 611 NodeISayHelloListener_middle *ptr = new NodeISayHelloListener_middle(); 612 ptr->NodeISayHelloListener_onSayHelloEndCallbackMiddle(eventName, info); 613 delete ptr; 614} 615 616bool funcTest(bool& v, std::string& out) 617{ 618 if (v) { 619 out = "ret is true"; 620 } else { 621 out = "ret is false"; 622 } 623 return true; 624} 625} 626} 627 628``` 629 630##### 增加子系统 631 632在源码/build/subsystem_config.json中增加子系统选项。如下所示: 633 634``` 635"napitest": { 636 "project": "hmf/napitest", 637 "path": "foundation/napitest", 638 "name": "napitest", 639 "dir": "foundation" 640 } 641``` 642 643#### 添加功能模块 644 645在产品配置中添加上述子系统的功能模块,编译到产品产出文件中,例如在源码/productdefine/common/products/rk3566.json中增加part选项,其中the first napitest就是BUILD.gn文件中的subsystem_name,第二个napitest就是BUILD.gn文件中的part_name。 646 647 "napitest:napitest":{} 648 649#### 编译验证 650 651编译成功后,就会在 /out/产品名/packages/phone/system/lib/module/ 生成libnapitest.z.so,如下所示: 652 653 /out/ohos-arm-release/packages/phone/system/lib/module 654 655