【问题标题】:How can I read an existing directory from WASM in Rust using wasmer-wasi?如何使用 wasmer-wasi 从 Rust 中的 WASM 读取现有目录?
【发布时间】:2021-01-31 10:55:16
【问题描述】:

我写了一个简单的 wasmer-wasi 示例,它读取目录条目但总是失败。

wasi_fs_example/src/lib.rs:

#[no_mangle]
pub fn start() {
    std::fs::read_dir("/").unwrap();
}

runner/src/main.rs:

use wasmer::{Instance, Module, Store};
use wasmer_wasi::WasiState;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let wasm = std::fs::read("target/wasm32-wasi/debug/wasi_fs_example.wasm")?;

    let store = Store::default();
    let module = Module::new(&store, wasm)?;

    let mut wasi_env = WasiState::new("wasi_fs_example")
        .preopen_dir("target")?
        .finalize()?;

    let import_object = wasi_env.import_object(&module)?;
    let instance = Instance::new(&module, &import_object)?;

    let start = instance.exports.get_function("start")?;
    start.call(&[])?;

    Ok(())
}

这会在运行时产生错误:

cargo build -p wasi_fs_example --target wasm32-wasi
cargo run -p runner
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "failed to find a pre-opened file descriptor through which \"/\" could be opened" }', wasi_fs_example/src/lib.rs:6:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

示例的完整源代码位于here。为什么它不起作用?

【问题讨论】:

    标签: rust webassembly wasi


    【解决方案1】:

    目前在 Rust 中,我们实际上只能创建 WASI 二进制文件,而不是库。 WASI 仅在需要存在的主要功能期间有效。从其他任何地方调用 wasi 函数都会出现段错误,因为 libpreopen 未初始化。

    总结一下,目前如何解决这个问题:

    • 根本没有lib.crate-type
    • 将文件设为src/main.rs,而不是src/lib.rs
    • src/main.rs 的顶部有#![no_main]
    • 使用RUSTFLAGS="-Z wasi-exec-model=reactor" cargo +nightly build --target wasm32-wasi
    • 请务必先致电_initialize

    https://github.com/WebAssembly/WASI/issues/24

    https://github.com/rust-lang/rust/pull/79997

    就我而言:

    wasi_fs_example/src/main.rs:

    #![no_main]
    
    #[no_mangle]
    pub extern "C" fn start() {
        std::fs::read_dir("/").unwrap();
    }
    

    runner/src/main.rs:

    ...
    let start = instance.exports.get_function("_initialize")?;
    start.call(&[])?;
    
    let start = instance.exports.get_function("start")?;
    start.call(&[])?;
    ...
    
    RUSTFLAGS="-Z wasi-exec-model=reactor" cargo +nightly build -p wasi_fs_example --target wasm32-wasi
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 2023-01-30
      • 1970-01-01
      • 2020-08-21
      • 2020-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多