Call Rust functions

If your Rust program has a main() function, you could compile it into a WASM bytecode file, and run it using the wasmedge CLI tool as a standalone application. However, a far more common use case is to compile a Rust function into a WASM bytecode file, and then call it from a host application. That is known as an embedded WASM function. The host application uses WasmEdge language SDKs (e.g., Go, Rust, C, Python and Node.js) to call those WASM functions compiled from Rust source code.

All the WasmEdge host language SDKs support simple function calls. However, the WASM spec only supports a few simple data types as call parameters and return values. The wasmedge-bindgen crate would transform call parameters and return values of Rust functions into simple integer types when the Rust function is compiled into WASM. For example, a string is automatically converted into two integers, a memory address and a length, which can be handled by the standard WASM spec. It is very easy to do this in Rust source code. Just annotate your function with the #[wasmedge-bindgen] macro. You can compile the annotated Rust code using the standard Rust compiler toolchain (e.g., the latest Cargo).

  1. #![allow(unused)]
  2. fn main() {
  3. use wasmedge_bindgen::*;
  4. use wasmedge_bindgen_macro::*;
  5. #[wasmedge_bindgen]
  6. pub fn say(s: String) -> Result<Vec<u8>, String> {
  7. let r = String::from("hello ");
  8. return Ok((r + s.as_str()).as_bytes().to_vec());
  9. }
  10. }

Of course, once the above Rust code is compiled into WASM, the function say() no longer takes the String parameter nor returns the Vec<u8>. So, the caller (i.e., the host application) must also deconstruct the call parameter into the memory pointer first before the call, and assemble the return value from the memory pointer after the call. These actions can be handled automagically by the WasmEdge language SDKs. To see a complete example, including the Rust WASM function and the Go host application, check out our tutorial in the Go SDK documentation.

A complete wasmedge-bindgen example in Rust (WASM) and Go (host)

Of course, the developer could choose to do wasmedge-bindgen‘s work by hand and pass a memory pointer directly. If you are interested in this approach to call Rust compiled WASM functions, check out our examples in the Go SDK.