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 11Node-API中的napi_load_module接口的功能是在主线程中进行模块的加载,当模块加载出来之后,可以使用函数napi_get_property获取模块导出的变量,也可以使用napi_get_named_property获取模块导出的函数。 12 13## 函数说明 14 15```cpp 16napi_status napi_load_module(napi_env env, const char* path, napi_value* result); 17``` 18 19| 参数 | 说明 | 20| :------------- | :----------------------------- | 21| env | 当前的虚拟机环境 | 22| path | 加载的文件路径或者模块名 | 23| result | 加载的模块 | 24 25## 使用限制 26 27- 禁止在非主线程当中使用该接口。 28- 禁止在Init函数中使用该接口。 29- 禁止在线程安全函数的回调函数当中进行文件路径的加载。 30 31建议使用[napi_load_module_with_info](use-napi-load-module-with-info.md)来进行模块加载,该接口支持了更多的场景。 32 33## napi_load_module支持的场景 34| 场景 | 详细分类 | 说明 | 35| :------------- | :----------------------------- | :--------------------------- | 36| 系统模块 | 加载@ohos.*或 @system.* | - | 37| 本地工程模块 | 加载ets目录下文件中的模块 | 要求路径以ets开头 | 38| 本地工程模块 | 加载模块内文件路径 | 要求路径以moduleName开头 | 39| 本地工程模块 | 加载HAR模块名 | - | 40| 本地工程模块 | 加载HSP模块名 | - | 41| 远程包 | 加载远程HAR模块名 | - | 42| 远程包 | 加载ohpm包名 | - | 43| 模块Native库 | 加载libNativeLibrary.so | - | 44 45- **加载系统模块** 46 47 ```cpp 48 static napi_value loadModule(napi_env env, napi_callback_info info) { 49 // 1. 使用napi_load_module加载模块@ohos.hilog 50 napi_value result; 51 napi_status status = napi_load_module(env, "@ohos.hilog", &result); 52 if (status != napi_ok) { 53 return nullptr; 54 } 55 56 // 2. 使用napi_get_named_property获取info函数 57 napi_value infoFn; 58 status = napi_get_named_property(env, result, "info", &infoFn); 59 if (status != napi_ok) { 60 return nullptr; 61 } 62 63 napi_value tag; 64 std::string formatStr = "test"; 65 napi_create_string_utf8(env, formatStr.c_str(), formatStr.size(), &tag); 66 67 napi_value outputString; 68 std::string str = "Hello OpenHarmony"; 69 napi_create_string_utf8(env, str.c_str(), str.size(), &outputString); 70 71 napi_value flag; 72 napi_create_int32(env, 0, &flag); 73 74 napi_value args[3] = {flag, tag, outputString}; 75 // 3. 使用napi_call_function调用info函数 76 status = napi_call_function(env, result, infoFn, 3, args, nullptr); 77 if (status != napi_ok) { 78 return nullptr; 79 } 80 return result; 81 } 82 ``` 83 <!-- @[napi_load_module_napi_init](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIClassicUseCases/NodeAPILoadModule/entry/src/main/cpp/napi_init.cpp) --> 84 85- **加载ets目录下文件中的模块** 86 87 当加载文件中的模块时,如以下ArkTS代码: 88 89 ```javascript 90 //./src/main/ets/Test.ets 91 let value = 123; 92 function test() { 93 console.info("Hello OpenHarmony"); 94 } 95 export {value, test}; 96 ``` 97 <!-- @[napi_load_module_napi_test](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIClassicUseCases/NodeAPILoadModule/entry/src/main/ets/Test.ets) --> 98 991. 需要在工程的build-profile.json5文件中进行以下配置: 100 101 ```json 102 { 103 "buildOption" : { 104 "arkOptions" : { 105 "runtimeOnly" : { 106 "sources": [ 107 "./src/main/ets/Test.ets" 108 ] 109 } 110 } 111 } 112 } 113 ``` 114 <!-- @[napi_load_module_napi_build](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIClassicUseCases/NodeAPILoadModule/entry/build-profile.json5) --> 115 1162. 使用napi_load_module加载Test文件,调用函数test以及获取变量value: 117 118 ```cpp 119 static napi_value loadModule(napi_env env, napi_callback_info info) { 120 napi_value result; 121 // 1. 使用napi_load_module加载Test文件中的模块 122 napi_status status = napi_load_module(env, "ets/Test", &result); 123 if (status != napi_ok) { 124 return nullptr; 125 } 126 127 napi_value testFn; 128 // 2. 使用napi_get_named_property获取test函数 129 status = napi_get_named_property(env, result, "test", &testFn); 130 if (status != napi_ok) { 131 return nullptr; 132 } 133 // 3. 使用napi_call_function调用函数test 134 status = napi_call_function(env, result, testFn, 0, nullptr, nullptr); 135 if (status != napi_ok) { 136 return nullptr; 137 } 138 139 napi_value value; 140 napi_value key; 141 std::string keyStr = "value"; 142 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 143 // 4. 使用napi_get_property获取变量value 144 status = napi_get_property(env, result, key, &value); 145 if (status != napi_ok) { 146 return nullptr; 147 } 148 return result; 149 } 150 ``` 151 <!-- @[napi_load_module_napi_file](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIClassicUseCases/NodeAPILoadModule/entry/src/main/cpp/file.cpp) --> 152- **加载模块内文件路径** 153 154 当加载文件中的模块时,如以下ArkTS代码: 155 156 ```javascript 157 //./src/main/ets/Test.ets 158 let value = 123; 159 function test() { 160 console.info("Hello OpenHarmony"); 161 } 162 export {value, test}; 163 ``` 164 1651. 需要当前模块的build-profile.json5文件中进行以下配置: 166 167 ```json 168 { 169 "buildOption" : { 170 "arkOptions" : { 171 "runtimeOnly" : { 172 "sources": [ 173 "./src/main/ets/Test.ets" 174 ] 175 } 176 } 177 } 178 } 179 ``` 180 1812. 使用napi_load_module加载Test文件,调用函数test以及获取变量value: 182 183 ```cpp 184 static napi_value loadModule(napi_env env, napi_callback_info info) { 185 napi_value result; 186 // 1. 使用napi_load_module加载Test文件中的模块 187 napi_status status = napi_load_module(env, "entry/src/main/ets/Test", &result); 188 if (status != napi_ok) { 189 return nullptr; 190 } 191 192 napi_value testFn; 193 // 2. 使用napi_get_named_property获取test函数 194 status = napi_get_named_property(env, result, "test", &testFn); 195 if (status != napi_ok) { 196 return nullptr; 197 } 198 // 3. 使用napi_call_function调用函数test 199 status = napi_call_function(env, result, testFn, 0, nullptr, nullptr); 200 if (status != napi_ok) { 201 return nullptr; 202 } 203 204 napi_value value; 205 napi_value key; 206 std::string keyStr = "value"; 207 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 208 // 4. 使用napi_get_property获取变量value 209 status = napi_get_property(env, result, key, &value); 210 if (status != napi_ok) { 211 return nullptr; 212 } 213 return result; 214 } 215 ``` 216 217- **加载HAR模块名** 218 219 HAR包Index.ets文件如下: 220 221 ```javascript 222 //library Index.ets 223 let value = 123; 224 function test() { 225 console.info("Hello OpenHarmony"); 226 } 227 export {value, test}; 228 ``` 229 2301. 在当前模块下的oh-package.json5文件中配置dependencies项: 231 232 ```json 233 { 234 "dependencies": { 235 "library": "file:../library" 236 } 237 } 238 ``` 239 2402. 在使用library的模块中,对build-profile.json5进行配置: 241 242 ```json 243 { 244 "buildOption" : { 245 "arkOptions" : { 246 "runtimeOnly" : { 247 "packages": [ 248 "library" 249 ] 250 } 251 } 252 } 253 } 254 ``` 255 2563. 用napi_load_module加载library,调用函数test以及获取变量value: 257 258 ```cpp 259 static napi_value loadModule(napi_env env, napi_callback_info info) { 260 napi_value result; 261 // 1. 使用napi_load_module加载library 262 napi_status status = napi_load_module(env, "library", &result); 263 if (status != napi_ok) { 264 return nullptr; 265 } 266 267 napi_value testFn; 268 // 2. 使用napi_get_named_property获取test函数 269 status = napi_get_named_property(env, result, "test", &testFn); 270 if (status != napi_ok) { 271 return nullptr; 272 } 273 // 3. 使用napi_call_function调用函数test 274 status = napi_call_function(env, result, testFn, 0, nullptr, nullptr); 275 if (status != napi_ok) { 276 return nullptr; 277 } 278 279 napi_value value; 280 napi_value key; 281 std::string keyStr = "value"; 282 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 283 // 4. 使用napi_get_property获取变量value 284 status = napi_get_property(env, result, key, &value); 285 if (status != napi_ok) { 286 return nullptr; 287 } 288 return result; 289 } 290 ``` 291 292- **加载HSP模块名** 293 294 HSP包Index.ets文件如下: 295 296 ```javascript 297 //sharedlibrary Index.ets 298 let value = 123; 299 function test() { 300 console.info("Hello OpenHarmony"); 301 } 302 export {value, test}; 303 ``` 304 3051. 在当前模块下的oh-package.json5文件中配置dependencies项: 306 307 ```json 308 { 309 "dependencies": { 310 "sharedlibrary": "file:../sharedlibrary" 311 } 312 } 313 ``` 314 3152. 在使用library的模块中,对build-profile.json5进行配置: 316 317 ```json 318 { 319 "buildOption" : { 320 "arkOptions" : { 321 "runtimeOnly" : { 322 "packages": [ 323 "sharedlibrary" 324 ] 325 } 326 } 327 } 328 } 329 ``` 330 3313. 用napi_load_module加载sharedlibrary,调用函数test以及获取变量value: 332 333 ```cpp 334 static napi_value loadModule(napi_env env, napi_callback_info info) { 335 napi_value result; 336 // 1. 使用napi_load_module加载sharedlibrary 337 napi_status status = napi_load_module(env, "sharedlibrary", &result); 338 if (status != napi_ok) { 339 return nullptr; 340 } 341 342 napi_value testFn; 343 // 2. 使用napi_get_named_property获取test函数 344 status = napi_get_named_property(env, result, "test", &testFn); 345 if (status != napi_ok) { 346 return nullptr; 347 } 348 // 3. 使用napi_call_function调用函数test 349 status = napi_call_function(env, result, testFn, 0, nullptr, nullptr); 350 if (status != napi_ok) { 351 return nullptr; 352 } 353 354 napi_value value; 355 napi_value key; 356 std::string keyStr = "value"; 357 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 358 // 4. 使用napi_get_property获取变量value 359 status = napi_get_property(env, result, key, &value); 360 if (status != napi_ok) { 361 return nullptr; 362 } 363 return result; 364 } 365 ``` 366 367- **加载远程HAR模块名** 368 3691. 在当前模块下的oh-package.json5文件中配置dependencies项: 370 371 ```json 372 { 373 "dependencies": { 374 "@ohos/hypium": "1.0.16" 375 } 376 } 377 ``` 378 3792. 在使用@ohos/hypium的模块中,对build-profile.json5进行配置: 380 381 ```json 382 { 383 "buildOption" : { 384 "arkOptions" : { 385 "runtimeOnly" : { 386 "packages": [ 387 "@ohos/hypium" 388 ] 389 } 390 } 391 } 392 } 393 ``` 394 3953. 用napi_load_module加载@ohos/hypium,获取DEFAULT变量: 396 397 ```cpp 398 static napi_value loadModule(napi_env env, napi_callback_info info) { 399 napi_value result; 400 // 1. 使用napi_load_module加载@ohos/hypium 401 napi_status status = napi_load_module(env, "@ohos/hypium", &result); 402 if (status != napi_ok) { 403 return nullptr; 404 } 405 406 napi_value key; 407 std::string keyStr = "DEFAULT"; 408 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 409 // 2. 使用napi_get_property获取DEFAULT变量 410 napi_value defaultValue; 411 status = napi_get_property(env, result, key, &defaultValue); 412 if (status != napi_ok) { 413 return nullptr; 414 } 415 return result; 416 } 417 ``` 418 419- **加载ohpm包名** 420 4211. 在当前模块下的oh-package.json5文件中配置dependencies项: 422 423 ```json 424 { 425 "dependencies": { 426 "@ohos/axios": "2.2.4", 427 } 428 } 429 ``` 430 4312. 在使用@ohos/axios的模块中,对build-profile.json5进行配置: 432 433 ```json 434 { 435 "buildOption" : { 436 "arkOptions" : { 437 "runtimeOnly" : { 438 "packages": [ 439 "@ohos/axios" 440 ] 441 } 442 } 443 } 444 } 445 ``` 446 4473. 用napi_load_module加载@ohos/axios,获取VERSION变量: 448 449 ```cpp 450 static napi_value loadModule(napi_env env, napi_callback_info info) { 451 napi_value result; 452 // 1. 使用napi_load_module加载@ohos/axios 453 napi_status status = napi_load_module(env, "@ohos/axios", &result); 454 if (status != napi_ok) { 455 return nullptr; 456 } 457 458 napi_value key; 459 std::string keyStr = "VERSION"; 460 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 461 // 2. 使用napi_get_property获取VERSION 462 napi_value defaultValue; 463 status = napi_get_property(env, result, key, &defaultValue); 464 if (status != napi_ok) { 465 return nullptr; 466 } 467 return result; 468 } 469 ``` 470 471- **加载Native库** 472 473 libentry.so的index.d.ts文件如下: 474 475 ```javascript 476 //index.d.ts 477 export const add: (a: number, b: number) => number; 478 ``` 479 4801. 在当前模块下的oh-package.json5文件中配置dependencies项: 481 482 ```json 483 { 484 "dependencies": { 485 "libentry.so": "file:../src/main/cpp/types/libentry" 486 } 487 } 488 ``` 489 4902. 在使用libentry.so的模块中,对build-profile.json5进行配置: 491 492 ```json 493 { 494 "buildOption" : { 495 "arkOptions" : { 496 "runtimeOnly" : { 497 "packages": [ 498 "libentry.so" 499 ] 500 } 501 } 502 } 503 } 504 ``` 505 5063. 用napi_load_module加载libentry.so,调用函数add: 507 508 ```cpp 509 static napi_value loadModule(napi_env env, napi_callback_info info) { 510 napi_value result; 511 // 1. 使用napi_load_module加载libentry.so 512 napi_status status = napi_load_module(env, "libentry.so", &result); 513 if (status != napi_ok) { 514 return nullptr; 515 } 516 517 napi_value addFn; 518 // 2. 使用napi_get_named_property获取add函数 519 status = napi_get_named_property(env, result, "add", &addFn); 520 if (status != napi_ok) { 521 return nullptr; 522 } 523 524 napi_value a; 525 napi_value b; 526 napi_create_int32(env, 2, &a); 527 napi_create_int32(env, 3, &b); 528 napi_value args[2] = {a, b}; 529 // 3. 使用napi_call_function调用函数add 530 napi_value returnValue; 531 status = napi_call_function(env, result, addFn, 2, args, &returnValue); 532 if (status != napi_ok) { 533 return nullptr; 534 } 535 return result; 536 } 537 ``` 538 539- **HAR加载HAR模块名** 540 541 场景为har1加载har2,har2中的Index.ets文件如下: 542 543 ```javascript 544 //har2 Index.ets 545 let value = 123; 546 function test() { 547 console.info("Hello OpenHarmony"); 548 } 549 export {value, test}; 550 ``` 551 5521. 在har1中的oh-package.json5文件中配置dependencies项: 553 554 ```json 555 { 556 "dependencies": { 557 "har2": "file:../har2" 558 } 559 } 560 ``` 561 5622. 在har1的build-profile.json5文件中进行配置: 563 564 ```json 565 { 566 "buildOption" : { 567 "arkOptions" : { 568 "runtimeOnly" : { 569 "packages": [ 570 "har2" 571 ] 572 } 573 } 574 } 575 } 576 ``` 5773. 在har1中用napi_load_module加载har2,调用函数test以及获取变量value: 578 579 ```cpp 580 static napi_value loadModule(napi_env env, napi_callback_info info) { 581 napi_value result; 582 // 1. 使用napi_load_module加载har2 583 napi_status status = napi_load_module(env, "har2", &result); 584 if (status != napi_ok) { 585 return nullptr; 586 } 587 588 napi_value testFn; 589 // 2. 使用napi_get_named_property获取test函数 590 status = napi_get_named_property(env, result, "test", &testFn); 591 if (status != napi_ok) { 592 return nullptr; 593 } 594 // 3. 使用napi_call_function调用函数test 595 status = napi_call_function(env, result, testFn, 0, nullptr, nullptr); 596 if (status != napi_ok) { 597 return nullptr; 598 } 599 600 napi_value value; 601 napi_value key; 602 std::string keyStr = "value"; 603 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 604 // 4. 使用napi_get_property获取变量value 605 status = napi_get_property(env, result, key, &value); 606 if (status != napi_ok) { 607 return nullptr; 608 } 609 return result; 610 } 611 ```