Is there an example or gist anywhere of how to pass a string parameter to and then return a string back from a WebAssembly function? The host and the WASM function are both written in Rust.
I'm trying this for the host:
let func = instance
.get_typed_func::<(i32, i32), i32, _>(&mut context.store, &request.function_name)?;
unsafe {
let message_ptr = request.message.as_ptr() as i32;
let message_len = request.message.len() as i32;
let ret_ptr = func.call(&mut context.store, (message_ptr, message_len))?;
let ret_len = *((ret_ptr + 8) as *const i32) as usize;
let state = String::from_utf8(Vec::from_raw_parts(
*((ret_ptr + 0) as *const i32) as *mut _,
ret_len,
ret_len,
))?;
...
}
and this as the WASM function:
#[no_mangle]
#[export_name = "handle_adjustment_message"]
unsafe extern "C" fn __wit_bindgen_handle_adjustment_message(
arg0: i32,
arg1: i32,
) -> i32 {
let len0 = arg1 as usize;
let message = String::from_utf8(Vec::from_raw_parts(arg0 as *mut _, len0, len0)).unwrap();
... process ..
let ret_string: String = ...
let vec3 = (ret_string.into_bytes()).into_boxed_slice();
let ptr3 = vec3.as_ptr() as i32;
let len3 = vec3.len() as i32;
core::mem::forget(vec3);
let ptr4 = RET_AREA.as_mut_ptr() as i32;
*((ptr4 + 8) as *mut i32) = len3;
*((ptr4 + 0) as *mut i32) = ptr3;
ptr4
}
One way to do it is to write a wit file describing the API, and use wit-bindgen to generate the bindings. It supports string
arguments and return values, and generates convenient Rust bindings for host and guest code.
Thanks @Dan Gohman - so if I have a .wit file that looks like:
handler: function(message: string) -> string
Then I should build the bindings for the host with:
$ wit-bindgen wasmtime --import handler.wit
and the rust WASM function with:
$ wit-bindgen rust-wasm --export handler.wit
Is that right?
If so, the WASM side bindings make sense and are straightforward, but the host side bindings include a reference to wit_bindgen_wasmtime which doesn't seem to exist as a crate?
wit_bindgen_wasmtime is in the wit-bindgen repo
It's not published on crates.io just yet.
Ah I see its in wit-bindgen/crates/wasmtime
- ok, thanks.
Sorry - hopefully final question - is there any example that uses the generated host module/struct bindings? (In particular, confused on what to pass the get_state
parameter of the new
function.)
I don't know that offhand. I'll look into it and let you know
Thanks @Dan Gohman for all of your help - I think I have figured out most everything. The remaining issue I seem to be down to is figuring out why my WASM modules doesn't expose canonical_abi_free
and canonical_abi_realloc
.
Also for future readers @Radu Matei has an example repo here https://github.com/radu-matei/wasm-components-example
... and answer to getting canonical_abi_free
and canonical_abi_realloc
exposed is to use the wit_bindgen_rust::export!
macro ...
Last updated: Dec 23 2024 at 13:07 UTC