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