This question is based on this discussion. I need to return different structures, Option, Result. I noticed the externalref crate, but it is in experimental status and I can't use it.
I was trying to do something like this:
#[repr(C)]
pub struct WasmResult {
pub ok: i32,
pub err_len: usize,
pub err_ptr: *const u8,
}
#[no_mangle]
pub extern "C" fn test_string() -> WasmResult {
let error_message = "An error message from Rust";
let error_bytes = error_message.as_bytes();
WasmResult {
ok: 0,
err_len: error_bytes.len(),
err_ptr: error_bytes.as_ptr(),
}
}
Host:
use anyhow::Result;
use wasmtime::*;
use wasmtime_wasi::WasiCtxBuilder;
#[repr(C)]
pub struct WasmResult {
pub ok: i32,
pub err_len: usize,
pub err_ptr: *const u8,
}
fn main() -> Result<()> {
println!("Compiling module...");
let mut config = Config::new();
config.wasm_reference_types(true);
let engine = Engine::new(&config)?;
let module = Module::from_file(&engine, "../target/wasm32-unknown-unknown/release/rust_wasm.wasm")?;
println!("Initializing...");
let linker = Linker::new(&engine);
let wasi = WasiCtxBuilder::new()
.inherit_stdio()
.inherit_args()
.expect("should always be able to inherit args")
.build();
let mut store = Store::new(&engine, wasi);
let instance = linker.instantiate(&mut store, &module)?;
let Ok(test_len) = instance.get_typed_func::<(), WasmResult>(&mut store, "test_string") else {
anyhow::bail!("Failed to get WasmResult");
};
let test_string = test_len.call(&mut store, ())?.unwrap();
Ok(())
}
I also tried to do this with wasmtime::ExternRef, but I don't know how I can implement the logic in the crate built into wasm without using the externref crate.
I also want to note that I need to call wasm functions from Rust, not from Js.