Embedding WebAssembly in your Rust application
Tags: rust, webassembly
Published: 2019-01-29 00:25:10

---
title: Embedding WebAssembly in your Rust application
published: true
description: Embedding WebAssembly in your Rust application
tags: #rust #webassembly
---



[Wasmer](https://wasmer.io) is a WebAssembly runtime designed to run both standalone and embedded.

The crate [wasmer-runtime](https://github.com/wasmerio/wasmer/tree/master/lib#Runtime) exposes an easy to use and safe api for compiling, creating imports, and calling WebAssembly from your own library.

![Rust-Wasmer](https://thepracticaldev.s3.amazonaws.com/i/ls54gl9rt8ndpyti0378.png)

This tutorial goes over how to make a simple wasm application and run it using the wasmer-runtime!

# Creating a Wasm Application

Our sample application is just a basic “Hello, World!” program. Because WebAssembly doesn’t inherently have any way to print to the command line, we have to import such a function from our environment.

In this case, we define an imported `print_str` function.

```rust
// Define a function that is imported into the module.
// By default, the "env" namespace is used.
extern "C" {
    fn print_str(ptr: *const u8, len: usize);
}

// Define a string that is accessible within the wasm
// linear memory.
static HELLO: &'static str = "Hello, World!";

// Export a function named "hello_wasm". This can be called
// from the embedder!
#[no_mangle]
pub extern fn hello_wasm() {
    // Call the function we just imported and pass in
    // the offset of our string and its length as parameters.
    unsafe {
      print_str(HELLO.as_ptr(), HELLO.len());
    }
}
```

When the `hello_wasm` function is called by the embedder, it will proceed to call the imported `print_str` function with a pointer to the “Hello, World!” string and its length as arguments.

# Embedding WebAssembly using Wasmer!

This example shows to use use the [wasmer-runtime](https://crates.io/crates/wasmer-runtime/) crate to compile and run WebAssembly!

Since our Wasm application imported a function print_str, we must create an `ImportObject` containing the implementation of that function.

While you can manually (and unsafely) fill in the import object yourself, we’ve defined a useful macro that does function signature checking automatically to make it easier and safer.

```rust
use std::str;
use wasmer_runtime::{
    imports,
    instantiate,
    error,
    Ctx,
};

// Make sure that the compiled wasm-sample-app is accessible at this path.
static WASM: &'static [u8] = include_bytes!("../wasm-sample-app/target/wasm32-unknown-unknown/release/wasm_sample_app.wasm");

fn main() -> error::Result<()> {
    // Let's define the import object used to import our function
    // into our webassembly sample application.
    //
    // We've defined a macro that makes it super easy.
    //
    // The signature tells the runtime what the signature (the parameter
    // and return types) of the function we're defining here is.
    // The allowed types are `i32`, `u32`, `i64`, `u64`,
    // `f32`, and `f64`.
    //
    // Make sure to check this carefully!
    let import_object = imports! {
        // Define the "env" namespace that was implicitly used
        // by our sample application.
        "env" => {
            // name         // func    // signature
            "print_str" => print_str<[u32, u32] -> []>,
        },
    };

    // Compile our webassembly into an `Instance`.
    let mut instance = instantiate(WASM, import_object)?;

    // Call our exported function!
    instance.call("hello_wasm", &[])?;

    Ok(())
}

// Let's define our "print_str" function.
//
// The declaration must start with "extern" or "extern "C"".
extern fn print_str(ptr: u32, len: u32, ctx: &mut Ctx) {
    // Get a slice that maps to the memory currently used by the webassembly
    // instance.
    //
    // Webassembly only supports a single memory for now,
    // but in the near future, it'll support multiple.
    //
    // Therefore, we don't assume you always just want to access first
    // memory and force you to specify the first memory.
    let memory = ctx.memory(0);

    // Get a subslice that corresponds to the memory used by the string.
    let str_slice = &memory[ptr as usize..(ptr + len) as usize];

    // Convert the subslice to a `&str`.
    let string = str::from_utf8(str_slice).unwrap();

    // Print it!
    println!("{}", string);
}
```


This example is hosted on Github. Check out the Readme for instructions on how to try it out for yourself!

[Example of Using Wasmer from Rust](https://github.com/wasmerio/wasmer-rust-example)

If you have feedback, issues, or feature requests please open an issue in our [Github repository](https://github.com/wasmerio/wasmer).

We look forward to what cool things you build with WebAssembly and our new embeddable runtime!