• 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)中使用。
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。
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.soindex.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