• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ts41> 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.soindex.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