1# 使用Node-API接口进行模块加载 2 3Node-API中的napi_load_module_with_info接口的功能是进行模块的加载,当模块加载出来之后,可以使用函数napi_get_property获取模块导出的变量,也可以使用napi_get_named_property获取模块导出的函数,该函数可以在[新创建的ArkTS基础运行时环境](use-napi-ark-runtime.md)中使用,即napi_create_ark_runtime接口创建的运行时环境。 4 5## 函数说明 6 7```cpp 8napi_status napi_load_module_with_info(napi_env env, 9 const char* path, 10 const char* module_info, 11 napi_value* result); 12``` 13 14| 参数 | 说明 | 15| :------------- | :----------------------------- | 16| env | 当前的虚拟机环境 | 17| path | 加载的文件路径或者模块名 | 18| module_info | bundleName/moduleName的路径拼接 | 19| result | 加载的模块 | 20 21> **注意** 22> 23> 1. bundleName表示AppScope/app.json5中配置的工程名; 24> 2. moduleName指的是待加载模块所在的HAP下module.json5中配置的名字; 25> 3. [napi_load_module](use-napi-load-module.md)只局限于在主线程中进行模块加载。 26 27## napi_load_module_with_info支持的场景 28 29| 场景 | 详细分类 | 说明 | 30| :------------- | :----------------------------- | :--------------------------- | 31| 本地工程模块 | 加载模块内文件路径 | 要求路径以moduleName开头 | 32| 本地工程模块 | 加载HAR模块名 | - | 33| 远程包 | 加载远程HAR模块名 | - | 34| 远程包 | 加载ohpm包名 | - | 35| API | 加载@ohos.*或 @system.* | - | 36| 模块Native库 | 加载libNativeLibrary.so | - | 37 38> **注意** 39> 40> 1. 加载一个模块名,实际的行为是加载该模块的入口文件,一般为index.ets/ts。 41> 2. 如果在HAR中加载另外一个HAR,需要确保module_info的配置正确,尤其注意moduleName应为HAP的moduleName或者HSP的moduleName。 42> 3. 如果在HAP/HSP中直接或间接使用了三方包,该三方包中使用napi_load_module_with_info接口加载其他模块A,则需要在HAP/HSP中也添加A的依赖。 43 44## 异常场景 451. 加载hsp失败,返回错误码`napi_generic_failure`。 462. 在模块加载过程中,若出现链接关系错误或包内未找到对应文件等问题,该API将抛出referenceError异常,并返回错误码`napi_pending_exception`。 473. 系统侧发生非预期行为导致加载模块无法正常执行,将抛出cppcrash。 48 49## 使用示例 50 51- **加载模块内文件路径** 52 53当加载文件中的模块时,如以下ArkTS代码: 54 55```javascript 56//./src/main/ets/Test.ets 57let value = 123; 58function test() { 59 console.log("Hello OpenHarmony"); 60} 61export {value, test}; 62``` 63 641. 当前模块的build-profile.json5文件中需进行以下配置: 65 66 ```json 67 { 68 "buildOption" : { 69 "arkOptions" : { 70 "runtimeOnly" : { 71 "sources": [ 72 "./src/main/ets/Test.ets" 73 ] 74 } 75 } 76 } 77 } 78 ``` 79 802. 使用napi_load_module_with_info加载Test文件,调用函数test以及获取变量value。 81 82 > **注意** 83 > 84 >开启useNormalizedOHMUrl后(即将工程目录中与entry同级别的应用级build-profile.json5文件中strictMode属性的useNormalizedOHMUrl字段配置为true),加载模块内文件路径时:1. bundleName不会影响最终加载逻辑,会智能通过module名索引进程内对应的hap,例如:工程的bundleName为com.example.application,实际入参时填写为 com.example.application1,模块也能正常加载。2. 路径需要以packageName开头,packageName指的是模块的oh-package.json5中配置的name字段。 85 86 87 ```cpp 88 static napi_value loadModule(napi_env env, napi_callback_info info) { 89 napi_value result; 90 // 1. 使用napi_load_module_with_info加载Test文件中的模块 91 napi_status status = napi_load_module_with_info(env, "entry/src/main/ets/Test", "com.example.application/entry", &result); 92 if (status != napi_ok) { 93 return nullptr; 94 } 95 96 napi_value testFn; 97 // 2. 使用napi_get_named_property获取test函数 98 napi_get_named_property(env, result, "test", &testFn); 99 // 3. 使用napi_call_function调用函数test 100 napi_call_function(env, result, testFn, 0, nullptr, nullptr); 101 102 napi_value value; 103 napi_value key; 104 std::string keyStr = "value"; 105 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 106 // 4. 使用napi_get_property获取变量value 107 napi_get_property(env, result, key, &value); 108 return result; 109 } 110 ``` 111 112- **加载源码HAR模块** 113 114HAR包Index.ets文件如下: 115 116 ```javascript 117 //library Index.ets 118 let value = 123; 119 function test() { 120 console.log("Hello OpenHarmony"); 121 } 122 export {value, test}; 123 ``` 124 1251. 在oh-package.json5文件中配置dependencies项: 126 127 ```json 128 { 129 "dependencies": { 130 "library": "file:../library" 131 } 132 } 133 ``` 134 1352. 在使用library的模块中,对build-profile.json5进行配置: 136 137 ```json 138 { 139 "buildOption" : { 140 "arkOptions" : { 141 "runtimeOnly" : { 142 "packages": [ 143 "library" 144 ] 145 } 146 } 147 } 148 } 149 ``` 150 1513. 使用napi_load_module_with_info加载library,调用函数test以及获取变量value: 152 153 ```cpp 154 static napi_value loadModule(napi_env env, napi_callback_info info) { 155 napi_value result; 156 // 1. 使用napi_load_module_with_info加载library 157 napi_status status = napi_load_module_with_info(env, "library", "com.example.application/entry", &result); 158 if (status != napi_ok) { 159 return nullptr; 160 } 161 162 napi_value testFn; 163 // 2. 使用napi_get_named_property获取test函数 164 napi_get_named_property(env, result, "test", &testFn); 165 // 3. 使用napi_call_function调用函数test 166 napi_call_function(env, result, testFn, 0, nullptr, nullptr); 167 168 napi_value value; 169 napi_value key; 170 std::string keyStr = "value"; 171 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 172 // 4. 使用napi_get_property获取变量value 173 napi_get_property(env, result, key, &value); 174 return result; 175 } 176 ``` 177 178- **加载远程HAR模块名** 179 1801. 在oh-package.json5文件中配置dependencies项: 181 182 ```json 183 { 184 "dependencies": { 185 "@ohos/hypium": "1.0.16" 186 } 187 } 188 ``` 189 1902. 在使用@ohos/hypium的模块中,对build-profile.json5进行配置: 191 192 ```json 193 { 194 "buildOption" : { 195 "arkOptions" : { 196 "runtimeOnly" : { 197 "packages": [ 198 "@ohos/hypium" 199 ] 200 } 201 } 202 } 203 } 204 ``` 205 2063. 使用napi_load_module_with_info加载@ohos/hypium,获取DEFAULT变量: 207 208 ```cpp 209 static napi_value loadModule(napi_env env, napi_callback_info info) { 210 napi_value result; 211 // 1. 使用napi_load_module_with_info加载@ohos/hypium 212 napi_status status = napi_load_module_with_info(env, "@ohos/hypium", "com.example.application/entry", &result); 213 if (status != napi_ok) { 214 return nullptr; 215 } 216 217 napi_value key; 218 std::string keyStr = "DEFAULT"; 219 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 220 // 2. 使用napi_get_property获取DEFAULT变量 221 napi_value defaultValue; 222 napi_get_property(env, result, key, &defaultValue); 223 return result; 224 } 225 ``` 226 227- **加载ohpm包名** 228 2291. 在oh-package.json5文件中配置dependencies项: 230 231 ```json 232 { 233 "dependencies": { 234 "json5": "^2.2.3" 235 } 236 } 237 ``` 238 2392. 在使用json5的模块中,对build-profile.json5进行配置: 240 241 ```json 242 { 243 "buildOption" : { 244 "arkOptions" : { 245 "runtimeOnly" : { 246 "packages": [ 247 "json5" 248 ] 249 } 250 } 251 } 252 } 253 ``` 254 2553. 用napi_load_module_with_info加载json5,调用函数stringify: 256 257 ```cpp 258 static napi_value loadModule(napi_env env, napi_callback_info info) { 259 napi_value result; 260 // 1. 使用napi_load_module_with_info加载json5 261 napi_status status = napi_load_module_with_info(env, "json5", "com.example.application/entry", &result); 262 if (status != napi_ok) { 263 return nullptr; 264 } 265 266 napi_value key; 267 std::string keyStr = "default"; 268 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 269 // 2. 使用napi_get_property获取default对象 270 napi_value defaultValue; 271 napi_get_property(env, result, key, &defaultValue); 272 273 napi_value stringifyFn; 274 // 3. 使用napi_get_named_property获取stringify函数 275 napi_get_named_property(env, defaultValue, "stringify", &stringifyFn); 276 // 4. 使用napi_call_function调用函数stringify 277 napi_value argStr; 278 std::string text = "call json5 stringify"; 279 napi_create_string_utf8(env, text.c_str(), text.size(), &argStr); 280 napi_value args[1] = {argStr}; 281 282 napi_value returnValue; 283 napi_call_function(env, defaultValue, stringifyFn, 1, args, &returnValue); 284 return result; 285 } 286 ``` 287 288- **加载API模块** 289 290```cpp 291static napi_value loadModule(napi_env env, napi_callback_info info) { 292 // 1. 使用napi_load_module_with_info加载模块@ohos.hilog 293 napi_value result; 294 napi_status status = napi_load_module_with_info(env, "@ohos.hilog", nullptr, &result); 295 if (status != napi_ok) { 296 return nullptr; 297 } 298 299 // 2. 使用napi_get_named_property获取info函数 300 napi_value infoFn; 301 napi_get_named_property(env, result, "info", &infoFn); 302 303 napi_value tag; 304 std::string formatStr = "test"; 305 napi_create_string_utf8(env, formatStr.c_str(), formatStr.size(), &tag); 306 307 napi_value outputString; 308 std::string str = "Hello OpenHarmony"; 309 napi_create_string_utf8(env, str.c_str(), str.size(), &outputString); 310 311 napi_value flag; 312 napi_create_int32(env, 0, &flag); 313 314 napi_value args[3] = {flag, tag, outputString}; 315 // 3. 使用napi_call_function调用info函数 316 napi_call_function(env, result, infoFn, 3, args, nullptr); 317 return result; 318} 319``` 320 321- **加载Native库** 322 323libentry.so的index.d.ts文件如下: 324 325```javascript 326//index.d.ts 327export const add: (a: number, b: number) => number; 328``` 329 3301. 在oh-package.json5文件中配置dependencies项: 331 332 ```json 333 { 334 "dependencies": { 335 "libentry.so": "file:../src/main/cpp/types/libentry" 336 } 337 } 338 ``` 339 3402. 在使用libentry.so的模块中,对build-profile.json5进行配置: 341 342 ```json 343 { 344 "buildOption" : { 345 "arkOptions" : { 346 "runtimeOnly" : { 347 "packages": [ 348 "libentry.so" 349 ] 350 } 351 } 352 } 353 } 354 ``` 355 3563. 用napi_load_module_with_info加载libentry.so,调用函数add: 357 358 ```cpp 359 static constexpr int INT_NUM_2 = 2; // int类型数值2 360 static constexpr int INT_NUM_3 = 3; // int类型数值3 361 362 static napi_value loadModule(napi_env env, napi_callback_info info) { 363 napi_value result; 364 // 1. 使用napi_load_module_with_info加载libentry.so 365 napi_status status = napi_load_module_with_info(env, "libentry.so", "com.example.application/entry", &result); 366 if (status != napi_ok) { 367 return nullptr; 368 } 369 370 napi_value addFn; 371 // 2. 使用napi_get_named_property获取add函数 372 napi_get_named_property(env, result, "add", &addFn); 373 374 napi_value a; 375 napi_value b; 376 napi_create_int32(env, INT_NUM_2, &a); 377 napi_create_int32(env, INT_NUM_3, &b); 378 napi_value args[2] = {a, b}; 379 // 3. 使用napi_call_function调用函数add 380 napi_value returnValue; 381 napi_call_function(env, result, addFn, INT_NUM_2, args, &returnValue); 382 return result; 383 } 384 ``` 385 386- **HAR加载HAR模块名** 387 388场景为har1加载har2,har2中的Index.ets文件如下: 389 390```javascript 391//har2 Index.ets 392let value = 123; 393function test() { 394 console.log("Hello OpenHarmony"); 395} 396export {value, test}; 397``` 398 3991. 在har1中的oh-package.json5文件中配置dependencies项: 400 401 ```json 402 { 403 "dependencies": { 404 "har2": "file:../har2" 405 } 406 } 407 ``` 408 4092. 在har1的build-profile.json5文件中进行配置: 410 411 ```json 412 { 413 "buildOption" : { 414 "arkOptions" : { 415 "runtimeOnly" : { 416 "packages": [ 417 "har2" 418 ] 419 } 420 } 421 } 422 } 423 ``` 424 4253. 在har1中使用napi_load_module_with_info加载har2,调用test函数并获取value变量: 426 427 ```cpp 428 static napi_value loadModule(napi_env env, napi_callback_info info) { 429 napi_value result; 430 // 1. 使用napi_load_module_with_info加载har2,注意这里的moduleName为模块所在HAP包的moduleName 431 napi_status status = napi_load_module_with_info(env, "har2", "com.example.application/entry", &result); 432 if (status != napi_ok) { 433 return nullptr; 434 } 435 436 napi_value testFn; 437 // 2. 使用napi_get_named_property获取test函数 438 napi_get_named_property(env, result, "test", &testFn); 439 // 3. 使用napi_call_function调用函数test 440 napi_call_function(env, result, testFn, 0, nullptr, nullptr); 441 442 napi_value value; 443 napi_value key; 444 std::string keyStr = "value"; 445 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 446 // 4. 使用napi_get_property获取变量value 447 napi_get_property(env, result, key, &value); 448 return result; 449 } 450 ``` 451