cargo-wasixでファイルの読み書きをするWasmプログラムを作成する
この記事では、cargo-wasix
を使用して、ファイルの読み書きを行うWebAssemblyプログラムを作成する方法を説明します。
cargo-wasixは、コマンドラインツールで、これは、WASIXをターゲットにしたアプリケーションのビルドが簡単できます。
WASIXは、WASI (WebAssembly System Interface) の機能を拡張し、ネットワーキングやスレッドなどの追加機能を含むWebAssembly (WASM) の拡張仕様です。Wasmer社によって開発されています。
cargo-wasixを通さなくても、WASIXに準拠したバイナリをビルドすることはできますが、システムコールの追加サポートやWASIX固有のライブラリとの互換性など、cargo-wasixが提供するビルドサポートを利用した方が簡単です。
WASIでは基本的なファイルの読み書きはサポートされています。Rustの標準ライブラリを使用してファイルの読み書きを行うプログラムを作成してwasmファイルをビルドし、Wasmerで実行します。
プロジェクトの作成
まず、新しいCargoプロジェクトを作成します。
❯ cargo new wasix-io-example
Creating binary (application) `wasix-io-example` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
次に、プロジェクトディレクトリに移動します。
❯ cd wasix-io-example
Rustコードの作成
以下のコードをsrc/main.rs
に追加します。このプログラムは、指定されたファイルの内容を読み取り、整数として解釈し、その値をインクリメントしてファイルに書き戻します。
use std::fs::OpenOptions;
use std::io::{Read, Seek, SeekFrom, Write};
use std::{env, str};
fn increment_counter(file_path: &str) -> Result<i32, Box<dyn std::error::Error>> {
let mut file = OpenOptions::new().read(true).write(true).open(file_path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
let contents = str::from_utf8(&buffer)?;
println!("File contents: {}", contents);
let counter: i32 = contents.trim().parse()?;
let new_counter = counter + 1;
file.set_len(0)?;
file.seek(SeekFrom::Start(0))?;
file.write_all(new_counter.to_string().as_bytes())?;
println!("Counter incremented to {}", new_counter);
Ok(new_counter)
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {} <file_path>", args[0]);
std::process::exit(1);
}
let file_path = &args[1];
match increment_counter(file_path) {
Ok(_) => println!("Counter incremented successfully"),
Err(e) => eprintln!("Failed to increment counter: {}", e),
}
}
cargo-wasixのインストールとビルド
次に、cargo-wasix
をインストールします。
❯ cargo install cargo-wasix
プロジェクトをビルドします。
❯ cargo wasix build
Compiling wasix-io-example v0.1.0 (wasix-io-example)
warning: unstable feature specified for `-Ctarget-feature`: `atomics`
|
= note: this feature is not stably supported; its behavior can change in the future
warning: `wasix-io-example` (bin "wasix-io-example") generated 1 warning
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s
info: Post-processing WebAssembly files
Optimizing with wasm-opt
実行
カウンターファイルを作成し、初期値を設定します。
❯ echo 0 > counter.txt
WebAssemblyプログラムを実行します。
❯ wasmer run target/wasm32-wasmer-wasi/debug/wasix-io-example.rustc.wasm ./counter.txt --dir .
File contents: 0
Counter incremented to 1
Counter incremented successfully
これで、ファイルの内容がインクリメントされ、結果が表示されます。
--dir .
は、プログラムがファイルを読み書きするためのディレクトリを指定します。これはしないと、ファイルの読み書きができません。
❯ wasmer run target/wasm32-wasmer-wasi/debug/wasix-io-example.rustc.wasm ./counter.txt
Failed to increment counter: No such file or directory (os error 44)
Discussion