1# 使用Node-API接口进行模块加载 2 3Node-API中的napi_load_module_with_info接口的功能是进行模块的加载,当模块加载出来之后,可以使用函数napi_get_property获取模块导出的变量,也可以使用napi_get_named_property获取模块导出的函数,该函数可以在[新创建的ArkTS基础运行时环境](use-napi-ark-runtime.md)中使用。 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。 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 ```cpp 87 static napi_value loadModule(napi_env env, napi_callback_info info) { 88 napi_value result; 89 // 1. 使用napi_load_module_with_info加载Test文件中的模块 90 napi_status status = napi_load_module_with_info(env, "entry/src/main/ets/Test", "com.example.application/entry", &result); 91 if (status != napi_ok) { 92 return nullptr; 93 } 94 95 napi_value testFn; 96 // 2. 使用napi_get_named_property获取test函数 97 napi_get_named_property(env, result, "test", &testFn); 98 // 3. 使用napi_call_function调用函数test 99 napi_call_function(env, result, testFn, 0, nullptr, nullptr); 100 101 napi_value value; 102 napi_value key; 103 std::string keyStr = "value"; 104 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 105 // 4. 使用napi_get_property获取变量value 106 napi_get_property(env, result, key, &value); 107 return result; 108 } 109 ``` 110 111- **加载HAR模块名** 112 113HAR包Index.ets文件如下: 114 115```javascript 116//library Index.ets 117let value = 123; 118function test() { 119 console.log("Hello OpenHarmony"); 120} 121export {value, test}; 122``` 123 1241. 在oh-package.json5文件中配置dependencies项: 125 126 ```json 127 { 128 "dependencies": { 129 "library": "file:../library" 130 } 131 } 132 ``` 133 1342. 在使用library的模块中,对build-profile.json5进行配置: 135 136 ```json 137 { 138 "buildOption" : { 139 "arkOptions" : { 140 "runtimeOnly" : { 141 "packages": [ 142 "library" 143 ] 144 } 145 } 146 } 147 } 148 ``` 149 1503. 用napi_load_module_with_info加载library,调用函数test以及获取变量value: 151 152 ```cpp 153 static napi_value loadModule(napi_env env, napi_callback_info info) { 154 napi_value result; 155 // 1. 使用napi_load_module_with_info加载library 156 napi_status status = napi_load_module_with_info(env, "library", "com.example.application/entry", &result); 157 if (status != napi_ok) { 158 return nullptr; 159 } 160 161 napi_value testFn; 162 // 2. 使用napi_get_named_property获取test函数 163 napi_get_named_property(env, result, "test", &testFn); 164 // 3. 使用napi_call_function调用函数test 165 napi_call_function(env, result, testFn, 0, nullptr, nullptr); 166 167 napi_value value; 168 napi_value key; 169 std::string keyStr = "value"; 170 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 171 // 4. 使用napi_get_property获取变量value 172 napi_get_property(env, result, key, &value); 173 return result; 174 } 175 ``` 176 177- **加载远程HAR模块名** 178 1791. 在oh-package.json5文件中配置dependencies项: 180 181 ```json 182 { 183 "dependencies": { 184 "@ohos/hypium": "1.0.16" 185 } 186 } 187 ``` 188 1892. 在使用@ohos/hypium的模块中,对build-profile.json5进行配置: 190 191 ```json 192 { 193 "buildOption" : { 194 "arkOptions" : { 195 "runtimeOnly" : { 196 "packages": [ 197 "@ohos/hypium" 198 ] 199 } 200 } 201 } 202 } 203 ``` 204 2053. 用napi_load_module_with_info加载@ohos/hypium,获取DEFAULT变量: 206 207 ```cpp 208 static napi_value loadModule(napi_env env, napi_callback_info info) { 209 napi_value result; 210 // 1. 使用napi_load_module_with_info加载@ohos/hypium 211 napi_status status = napi_load_module_with_info(env, "@ohos/hypium", "com.example.application/entry", &result); 212 if (status != napi_ok) { 213 return nullptr; 214 } 215 216 napi_value key; 217 std::string keyStr = "DEFAULT"; 218 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 219 // 2. 使用napi_get_property获取DEFAULT变量 220 napi_value defaultValue; 221 napi_get_property(env, result, key, &defaultValue); 222 return result; 223 } 224 ``` 225 226- **加载ohpm包名** 227 2281. 在oh-package.json5文件中配置dependencies项: 229 230 ```json 231 { 232 "dependencies": { 233 "json5": "^2.2.3" 234 } 235 } 236 ``` 237 2382. 在使用json5的模块中,对build-profile.json5进行配置: 239 240 ```json 241 { 242 "buildOption" : { 243 "arkOptions" : { 244 "runtimeOnly" : { 245 "packages": [ 246 "json5" 247 ] 248 } 249 } 250 } 251 } 252 ``` 253 2543. 用napi_load_module_with_info加载json5,调用函数stringify: 255 256 ```cpp 257 static napi_value loadModule(napi_env env, napi_callback_info info) { 258 napi_value result; 259 // 1. 使用napi_load_module_with_info加载json5 260 napi_status status = napi_load_module_with_info(env, "json5", "com.example.application/entry", &result); 261 if (status != napi_ok) { 262 return nullptr; 263 } 264 265 napi_value key; 266 std::string keyStr = "default"; 267 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 268 // 2. 使用napi_get_property获取default对象 269 napi_value defaultValue; 270 napi_get_property(env, result, key, &defaultValue); 271 272 napi_value stringifyFn; 273 // 3. 使用napi_get_named_property获取stringify函数 274 napi_get_named_property(env, defaultValue, "stringify", &stringifyFn); 275 // 4. 使用napi_call_function调用函数stringify 276 napi_value argStr; 277 std::string text = "call json5 stringify"; 278 napi_create_string_utf8(env, text.c_str(), text.size(), &argStr); 279 napi_value args[1] = {argStr}; 280 281 napi_value returnValue; 282 napi_call_function(env, defaultValue, stringifyFn, 1, args, &returnValue); 283 return result; 284 } 285 ``` 286 287- **加载API模块** 288 289```cpp 290static napi_value loadModule(napi_env env, napi_callback_info info) { 291 // 1. 使用napi_load_module_with_info加载模块@ohos.hilog 292 napi_value result; 293 napi_status status = napi_load_module_with_info(env, "@ohos.hilog", nullptr, &result); 294 if (status != napi_ok) { 295 return nullptr; 296 } 297 298 // 2. 使用napi_get_named_property获取info函数 299 napi_value infoFn; 300 napi_get_named_property(env, result, "info", &infoFn); 301 302 napi_value tag; 303 std::string formatStr = "test"; 304 napi_create_string_utf8(env, formatStr.c_str(), formatStr.size(), &tag); 305 306 napi_value outputString; 307 std::string str = "Hello OpenHarmony"; 308 napi_create_string_utf8(env, str.c_str(), str.size(), &outputString); 309 310 napi_value flag; 311 napi_create_int32(env, 0, &flag); 312 313 napi_value args[3] = {flag, tag, outputString}; 314 // 3. 使用napi_call_function调用info函数 315 napi_call_function(env, result, infoFn, 3, args, nullptr); 316 return result; 317} 318``` 319 320- **加载Native库** 321 322libentry.so的index.d.ts文件如下: 323 324```javascript 325//index.d.ts 326export const add: (a: number, b: number) => number; 327``` 328 3291. 在oh-package.json5文件中配置dependencies项: 330 331 ```json 332 { 333 "dependencies": { 334 "libentry.so": "file:../src/main/cpp/types/libentry" 335 } 336 } 337 ``` 338 3392. 在使用libentry.so的模块中,对build-profile.json5进行配置: 340 341 ```json 342 { 343 "buildOption" : { 344 "arkOptions" : { 345 "runtimeOnly" : { 346 "packages": [ 347 "libentry.so" 348 ] 349 } 350 } 351 } 352 } 353 ``` 354 3553. 用napi_load_module_with_info加载libentry.so,调用函数add: 356 357 ```cpp 358 static constexpr int INT_NUM_2 = 2; // int类型数值2 359 static constexpr int INT_NUM_3 = 3; // int类型数值3 360 361 static napi_value loadModule(napi_env env, napi_callback_info info) { 362 napi_value result; 363 // 1. 使用napi_load_module_with_info加载libentry.so 364 napi_status status = napi_load_module_with_info(env, "libentry.so", "com.example.application/entry", &result); 365 if (status != napi_ok) { 366 return nullptr; 367 } 368 369 napi_value addFn; 370 // 2. 使用napi_get_named_property获取add函数 371 napi_get_named_property(env, result, "add", &addFn); 372 373 napi_value a; 374 napi_value b; 375 napi_create_int32(env, INT_NUM_2, &a); 376 napi_create_int32(env, INT_NUM_3, &b); 377 napi_value args[2] = {a, b}; 378 // 3. 使用napi_call_function调用函数add 379 napi_value returnValue; 380 napi_call_function(env, result, addFn, INT_NUM_2, args, &returnValue); 381 return result; 382 } 383 ``` 384 385- **HAR加载HAR模块名** 386 387场景为har1加载har2,har2中的Index.ets文件如下: 388 389```javascript 390//har2 Index.ets 391let value = 123; 392function test() { 393 console.log("Hello OpenHarmony"); 394} 395export {value, test}; 396``` 397 3981. 在har1中的oh-package.json5文件中配置dependencies项: 399 400 ```json 401 { 402 "dependencies": { 403 "har2": "file:../har2" 404 } 405 } 406 ``` 407 4082. 在har1的build-profile.json5文件中进行配置: 409 410 ```json 411 { 412 "buildOption" : { 413 "arkOptions" : { 414 "runtimeOnly" : { 415 "packages": [ 416 "har2" 417 ] 418 } 419 } 420 } 421 } 422 ``` 423 4243. 在har1中用napi_load_module_with_info加载har2,调用函数test以及获取变量value: 425 426 ```cpp 427 static napi_value loadModule(napi_env env, napi_callback_info info) { 428 napi_value result; 429 // 1. 使用napi_load_module_with_info加载har2,注意这里的moduleName为模块所在HAP包的moduleName 430 napi_status status = napi_load_module_with_info(env, "har2", "com.example.application/entry", &result); 431 if (status != napi_ok) { 432 return nullptr; 433 } 434 435 napi_value testFn; 436 // 2. 使用napi_get_named_property获取test函数 437 napi_get_named_property(env, result, "test", &testFn); 438 // 3. 使用napi_call_function调用函数test 439 napi_call_function(env, result, testFn, 0, nullptr, nullptr); 440 441 napi_value value; 442 napi_value key; 443 std::string keyStr = "value"; 444 napi_create_string_utf8(env, keyStr.c_str(), keyStr.size(), &key); 445 // 4. 使用napi_get_property获取变量value 446 napi_get_property(env, result, key, &value); 447 return result; 448 } 449 ``` 450