|
| 1 | +--- |
| 2 | +sidebar_position: 1 |
| 3 | +--- |
| 4 | + |
| 5 | +## Using Plug-ins to Extend the Runtime in C |
| 6 | + |
| 7 | +The WasmEdge plug-ins are the shared libraries to provide the WasmEdge runtime to load and create host module instances. With the plug-ins, the WasmEdge runtime can be extended more easily. |
| 8 | + |
| 9 | +## Loading Plug-ins from Paths |
| 10 | + |
| 11 | +Developers can start using WasmEdge plug-ins by loading them from specific paths. To load plug-ins from the default paths, the following API can be used: |
| 12 | + |
| 13 | +```c |
| 14 | +WasmEdge_PluginLoadWithDefaultPaths(); |
| 15 | +``` |
| 16 | + |
| 17 | +Once this API is called, plug-ins from the default paths will be loaded. The default paths include: |
| 18 | + |
| 19 | +- The path specified in the `WASMEDGE_PLUGIN_PATH` environment variable. |
| 20 | +- The `../plugin/` directory relative to the WasmEdge installation path. |
| 21 | +- The `./wasmedge/` directory under the library path if WasmEdge is installed in a system directory (e.g., `/usr` and `/usr/local`). |
| 22 | + |
| 23 | +Developers can also load plug-ins from specific paths using this API: |
| 24 | + |
| 25 | +```c |
| 26 | +WasmEdge_PluginLoadFromPath("PATH_TO_PLUGIN/plugin.so"); |
| 27 | +``` |
| 28 | +
|
| 29 | +## Listing Loaded Plug-ins |
| 30 | +
|
| 31 | +Once plug-ins are loaded, developers can list the loaded plug-in names using the following approach: |
| 32 | +
|
| 33 | +```c |
| 34 | +WasmEdge_PluginLoadWithDefaultPaths(); |
| 35 | +printf("Number of loaded plug-ins: %d\n", WasmEdge_PluginListPluginsLength()); |
| 36 | +
|
| 37 | +WasmEdge_String Names[20]; |
| 38 | +uint32_t NumPlugins = WasmEdge_PluginListPlugins(Names, 20); |
| 39 | +for (int I = 0; I < NumPlugins; I++) { |
| 40 | + printf("Plug-in %d name: %s\n", I, Names[I].Buf); |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +## Getting Plug-in Context by Name |
| 45 | + |
| 46 | +Developers can obtain the plug-in context by its name using the following method: |
| 47 | + |
| 48 | +```c |
| 49 | +/* Assume that wasi_crypto plug-in is installed in the default plug-in path. */ |
| 50 | +WasmEdge_PluginLoadWithDefaultPaths(); |
| 51 | + |
| 52 | +const char PluginName[] = "wasi_crypto"; |
| 53 | +WasmEdge_String NameString = |
| 54 | + WasmEdge_StringWrap(PluginName, strlen(PluginName)); |
| 55 | +const WasmEdge_PluginContext *PluginCxt = WasmEdge_PluginFind(NameString); |
| 56 | +``` |
| 57 | +
|
| 58 | +## Creating Module Instances from Plug-ins |
| 59 | +
|
| 60 | +With the plug-in context, developers can create module instances by providing the module name: |
| 61 | +
|
| 62 | +```c |
| 63 | +/* Assume that the `PluginCxt` is the context to the wasi_crypto plug-in. */ |
| 64 | +
|
| 65 | +/* List the available host modules in the plug-in. */ |
| 66 | +WasmEdge_String Names[20]; |
| 67 | +uint32_t ModuleLen = WasmEdge_PluginListModule(PluginCxt, Names, 20); |
| 68 | +for (uint32_t I = 0; I < ModuleLen; I++) { |
| 69 | + /* Will print the available host module names in the plug-in. */ |
| 70 | + printf("%s\n", Names[I].Buf); |
| 71 | +} |
| 72 | +/* Will print here for the WASI-Crypto plug-in here: |
| 73 | + * wasi_ephemeral_crypto_asymmetric_common |
| 74 | + * wasi_ephemeral_crypto_common |
| 75 | + * wasi_ephemeral_crypto_kx |
| 76 | + * wasi_ephemeral_crypto_signatures |
| 77 | + * wasi_ephemeral_crypto_symmetric |
| 78 | + */ |
| 79 | +
|
| 80 | +/* Create a module instance from the plug-in by the module name. */ |
| 81 | +const char ModuleName[] = "wasi_ephemeral_crypto_common"; |
| 82 | +WasmEdge_String NameString = |
| 83 | + WasmEdge_StringWrap(ModuleName, strlen(ModuleName)); |
| 84 | +WasmEdge_ModuleInstance *ModCxt = |
| 85 | + WasmEdge_PluginCreateModule(PluginCxt, NameString); |
| 86 | +
|
| 87 | +WasmEdge_ModuleInstanceDelete(ModCxt); |
| 88 | +``` |
| 89 | + |
| 90 | +There may be several plug-ins in the default plug-in paths if users [installed WasmEdge plug-ins by the installer](/contribute/installer.md#plugins). |
| 91 | + |
| 92 | +Before using the plug-ins, developers should [Loading Plug-ins from Paths](#loading-plug-ins-from-paths). |
| 93 | + |
| 94 | +## Automatic Module Creation and Mocking |
| 95 | + |
| 96 | +Upon creating a `VM` context, the WasmEdge runtime will automatically create and register the modules of loaded plug-ins. In cases where specific plug-ins are not loaded, WasmEdge will provide mock implementations for certain host modules. These mocked modules include: |
| 97 | + |
| 98 | +- `wasi_ephemeral_crypto_asymmetric_common` (for the `WASI-Crypto`) |
| 99 | +- `wasi_ephemeral_crypto_common` (for the `WASI-Crypto`) |
| 100 | +- `wasi_ephemeral_crypto_kx` (for the `WASI-Crypto`) |
| 101 | +- `wasi_ephemeral_crypto_signatures` (for the `WASI-Crypto`) |
| 102 | +- `wasi_ephemeral_crypto_symmetric` (for the `WASI-Crypto`) |
| 103 | +- `wasi_ephemeral_nn` |
| 104 | +- `wasi_snapshot_preview1` |
| 105 | +- `wasmedge_httpsreq` |
| 106 | +- `wasmedge_process` |
| 107 | + |
| 108 | +## Handling Missing Plug-ins and Error Messages |
| 109 | + |
| 110 | +When the WASM want to invoke these host functions but the corresponding plug-in is not installed, WasmEdge will print the error message and return an error. |
| 111 | + |
| 112 | +```c |
| 113 | +/* Load the plug-ins in the default paths first. */ |
| 114 | +WasmEdge_PluginLoadWithDefaultPaths(); |
| 115 | +/* Create the configure context and add the WASI configuration. */ |
| 116 | +WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); |
| 117 | +WasmEdge_ConfigureAddHostRegistration(ConfCxt, |
| 118 | + WasmEdge_HostRegistration_Wasi); |
| 119 | +WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, NULL); |
| 120 | +WasmEdge_ConfigureDelete(ConfCxt); |
| 121 | +/* The following API can retrieve the registered modules in the VM context, |
| 122 | +* includes the built-in WASI and the plug-ins. |
| 123 | +*/ |
| 124 | +/* |
| 125 | +* This API will return `NULL` if the module instance is not found. |
| 126 | +*/ |
| 127 | +WasmEdge_String WasiName = |
| 128 | + WasmEdge_StringCreateByCString("wasi_snapshot_preview1"); |
| 129 | +/* The `WasiModule` will not be `NULL` because the configuration was set. */ |
| 130 | +const WasmEdge_ModuleInstanceContext *WasiModule = |
| 131 | + WasmEdge_VMGetRegisteredModule(VMCxt, WasiName); |
| 132 | +WasmEdge_StringDelete(WasiName); |
| 133 | +WasmEdge_String WasiNNName = |
| 134 | + WasmEdge_StringCreateByCString("wasi_ephemeral_nn"); |
| 135 | +/* The `WasiNNModule` will not be `NULL` even if the wasi_nn plug-in is not |
| 136 | +* installed, because the VM context will mock and register the host |
| 137 | +* modules. |
| 138 | +*/ |
| 139 | +const WasmEdge_ModuleInstanceContext *WasiNNModule = |
| 140 | + WasmEdge_VMGetRegisteredModule(VMCxt, WasiNNName); |
| 141 | +WasmEdge_StringDelete(WasiNNName); |
| 142 | + |
| 143 | +WasmEdge_VMDelete(VMCxt); |
| 144 | +``` |
0 commit comments