使用Rust结合Wasmtime调用WASI Preview1函数时遭遇链接错误求助
Rust结合Wasmtime调用WASI Preview1函数时遭遇链接错误求助
嘿,我明白你遇到这个链接错误有多头疼——刚接触WASI和Wasmtime的时候很容易踩这种顺序坑。咱们一步步理清楚问题出在哪:
核心问题:Linker绑定WASI导入的顺序完全搞反了
你的错误提示unknown import: wasi_snapshot_preview1::fd_filestat_get has not been defined,本质是因为你在实例化Wasm模块之后,才把WASI的函数添加到Linker里。Wasm模块在实例化时会立刻检查所有依赖的导入是否存在,这时候Linker里还没有WASI的函数绑定,自然找不到fd_filestat_get。
正确的顺序应该是:
- 创建Linker
- 将WASI Preview1的函数添加到Linker中
- 用这个已经绑定好导入的Linker去实例化Wasm模块
修正后的代码示例
我把你的main函数调整了顺序,同时修复了几个小细节(比如处理文件读取的错误):
use std::fs; use anyhow::Result; use wasmtime::Linker; use wasmtime::*; use wasmtime_wasi::p2::WasiCtxBuilder; use wasmtime_wasi::preview1::WasiP1Ctx; use wasmtime_wasi::{DirPerms, FilePerms}; fn main() -> Result<()> { // 先读取WAT文件,正确处理错误 let wat = fs::read_to_string("watcode.wat")?; // 构建WASI上下文 let wasi_ctx: WasiP1Ctx = WasiCtxBuilder::new() .preopened_dir(".", "/", DirPerms::READ, FilePerms::READ)? .build_p1(); let config = Config::new(); let engine: Engine = Engine::new(&config)?; let mut store = Store::new(&engine, wasi_ctx); // 1. 创建Linker let mut linker = Linker::new(&engine); // 2. 先把WASI Preview1的函数添加到Linker中! wasmtime_wasi::preview1::add_to_linker_sync(&mut linker, |s| s)?; // 3. 加载模块 let module: Module = Module::new(&engine, wat)?; // 4. 用绑定好导入的Linker实例化模块 let instance = linker.instantiate(&mut store, &module)?; // 调用导出函数 let get_file = instance.get_typed_func::<(), u32>(&mut store, "get_file")?; let error_code = get_file.call(&mut store, ())?; println!("get_file returned: {}", error_code); Ok(()) }
其他需要注意的细节
- 你编译Wasm用的
cargo build --target wasm32-wasip1是完全正确的,这个目标正好对应WASI Preview1标准,和Wasmtime的preview1模块匹配。 - 确保当前运行目录下存在
test.txt,并且你的程序有读取它的权限——不然即使链接成功,get_file也会返回1。 - 不需要手动把Wasm转成WAT再加载,你可以直接加载编译好的
.wasm文件:把Module::new(&engine, wat)?改成Module::from_file(&engine, "target/wasm32-wasip1/debug/your_crate_name.wasm")?,这样更高效也不容易出错。
按照这个修正后的代码运行,应该就能解决链接错误啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

