Project: WasmEdge Runtime (Runtime / Container Runtime)
File: say_hello.md

In this example, we'll use a wasm module, in which a function `run` is exported and it will call a function `sayhello` from an import module named `env`. The imported function `sayhello` has no inputs and outputs, and only prints a greeting message out. The code in the following example is verified on wasmedge-sdk v0.5.0 wasmedge-sys v0.10.0 wasmedge-types v0.3.0 Let's start off by getting all imports right away so you can follow along ```rust // please add this feature if you're using rust of version < 1.63 // #![feature(explicitgenericargswithimpl_trait)] use wasmedge_sdk::{ error::HostFuncError, host_function, params, wat2wasm, Caller, Executor, ImportObjectBuilder, Module, Store, WasmValue, }; ``` First, let's define a native function named `sayhelloworld` that prints out `Hello, World!`. ```rust fn sayhello(caller: &Caller, args: Vec<WasmValue>) -> Result<Vec<WasmValue>, HostFuncError> { println!("Hello, world!"); Ok(vec![]) } ``` To use the native function as an import function in the `WasmEdge` runtime, we need an `ImportObject`. `wasmedge-sdk` defines a , which provides a group of chaining methods used to create an `ImportObject`. Let's see how to do it. ```rust // create an import module let import = ImportObjectBuilder::new() .withfunc::<(), (), !>("sayhello", say_hello, None)? .build("env")?; ``` Now, we have an import module named `env` which holds a host function `say_hello`. As you may notice, the names we used for the import module and the host function are exactly the same as the ones appearing in the wasm module. You can find the wasm module in . Now, let's load a wasm module. `wasmedge-sdk` defines two methods in `Module`: loads a wasm module from a file, and meanwhile, validates the loaded wasm module. loads a wasm module from an array of in-memory bytes, and meanwhile, validates the loaded wasm module. Here we choose `Module::from_bytes` method to load our wasm module from an array of in-memory bytes. ```rust let wasm_bytes = wat2wasm( br#" (module ;; First we define a type with no parameters and no

(type $noargsnoretst (func (param) (result))) ;; Then we declare that we want to import a function named "env" "say_hello" with ;; that type signature. (import "env" "sayhello" (func $sayhello (type $noargsnoretst))) ;; Finally we create an entrypoint that calls our imported function. (func $run (type $noargsnoretst) (call $say_hello)) ;; And mark it as an exported function named "run". (export "run" (func $run))) "#, )?; // loads a wasm module from the given in-memory bytes and returns a compiled module let module = Module::frombytes(None, &wasmbytes)?; ``` To register a compiled module, we need to check if it has dependency on some import modules. In the wasm module this statement `(import "env" "sayhello" (func $sayhello (type $noargsnoretst)))` tells us that it depends on an import module named `env`. Therefore, we need to register the import module first before registering the compiled wasm module. ```rust // loads a wasm module from the given in-memory bytes let module = Module::frombytes(None, &wasmbytes)?; // create an executor let mut executor = Executor::new(None, None)?; // create a store let mut store = Store::new()?; // register the module into the store store.registerimportmodule(&mut executor, &import)?; // register the compiled module into the store and get an module instance let externinstance = store.registernamed_module(&mut executor, "extern", &module)?; ``` In the code above we use and to register the import module and the compiled module. `wasmedge-sdk` also provides alternative APIs to do the same thing: and . Now we are ready to run the exported function. ```rust // get the exported function "run" let run = extern_instance .func("run") .okorelse(|| anyhow::Error::msg("Not found exported function named 'run'."))?; // run host function run.call(&mut executor, params!())?; ``` In this example we created an instance of `Executor`, hence, we have two choices to call a : Any one of these two methods requires that you have to get a . In addition, defines a group of methods which can invoke host function in different ways. For details, please reference . The complete example can be found in .