wit-bindgen icon indicating copy to clipboard operation
wit-bindgen copied to clipboard

How to integrate wit with wasmtime?

Open zhenjunMa opened this issue 2 years ago • 2 comments

What I want to do

Hi, I am newer to wit-bindgen. I want to define an API for wasm module and the host, then, the wasm module can run in the host and interact by the API.

What I have tried

Guest

I use the README demo for my test.

wit/host.wit

default world host {
  import print: func(msg: string)

  export run: func()
}

src/lib.rs

wit_bindgen::generate!("host");

struct MyHost;

impl Host for MyHost {
    fn run() {
        print("hello wolrd!");
    }
}

export_host!(MyHost);

and I compile the lib.rs to wasm file as follow:

cargo build --target wasm32-unknown-unknown

Host

[dependencies]
wasmtime = "8.0.1"
use wasmtime::*;

fn main() -> wasmtime::Result<()> {
    let engine = Engine::default();
	// my_wasm.wasm was compiled by the guest above
    let module = Module::from_file(&engine, "xxx/my_wasm.wasm")?;

    let mut linker = Linker::new(&engine);
    linker.func_wrap("host", "print", |caller: Caller<'_, u32>, param: i32| {
        println!("{}", param);
        println!("my host state is: {}", caller.data());
    })?;

    let mut store = Store::new(&engine, 0);
    let instance = linker.instantiate(&mut store, &module)?;
    let hello = instance.get_typed_func::<(), ()>(&mut store, "run")?;
    hello.call(&mut store, ())?;

    Ok(())
}

I got an error...

Error: unknown import: `$root::print` has not been defined

so how to solve this problem? any ideas?

another question, the code below define the parm as i32, when I change the type to String、&str or &String

    linker.func_wrap("host", "print", |caller: Caller<'_, u32>, param: i32| {
        println!("{}", param);
        println!("my host state is: {}", caller.data());
    })?;

I got an error...

 IntoFunc<_, _, _>` is not satisfied
the trait `IntoFunc<_, _, _>` is not implemented for closure 

so how to define a host function that can receive a string param?

zhenjunMa avatar Apr 30 '23 03:04 zhenjunMa

Thanks for the report! When using components you'll want to use wasmtime::component::Linker, not wasmtime::Linker (as the latter is intended for core wasm modules). Does that help your use case?

alexcrichton avatar May 01 '23 15:05 alexcrichton

Here's a minimal example of linking a component from a project I made

HTML template component test

esoterra avatar May 01 '23 15:05 esoterra