嵌入 WASM 应用程序

WasmEdge Go SDK 能嵌入单独的 WebAssembly 应用程序 — 比如,一个带着 main() 函数,编译成 WebAssembly 的 Rust 应用程序。

我们的 demo Rust 应用程序从一个文件中读取内容。注意,WebAssembly 程序的输入和输出数据现在是通过 STDIN 和 STDOUT 传递的。

  1. use std::env;
  2. use std::fs::File;
  3. use std::io::{self, BufRead};
  4. fn main() {
  5. // 获取参数。
  6. let args: Vec<String> = env::args().collect();
  7. if args.len() <= 1 {
  8. println!("Rust: ERROR - No input file name.");
  9. return;
  10. }
  11. // 打开文件。
  12. println!("Rust: Opening input file \"{}\"...", args[1]);
  13. let file = match File::open(&args[1]) {
  14. Err(why) => {
  15. println!("Rust: ERROR - Open file \"{}\" failed: {}", args[1], why);
  16. return;
  17. },
  18. Ok(file) => file,
  19. };
  20. // 按行读取文件内容。
  21. let reader = io::BufReader::new(file);
  22. let mut texts:Vec<String> = Vec::new();
  23. for line in reader.lines() {
  24. if let Ok(text) = line {
  25. texts.push(text);
  26. }
  27. }
  28. println!("Rust: Read input file \"{}\" succeeded.", args[1]);
  29. // 获取 stdin 来打印内容。
  30. println!("Rust: Please input the line number to print the line of file.");
  31. let stdin = io::stdin();
  32. for line in stdin.lock().lines() {
  33. let input = line.unwrap();
  34. match input.parse::<usize>() {
  35. Ok(n) => if n > 0 && n <= texts.len() {
  36. println!("{}", texts[n - 1]);
  37. } else {
  38. println!("Rust: ERROR - Line \"{}\" is out of range.", n);
  39. },
  40. Err(e) => println!("Rust: ERROR - Input \"{}\" is not an integer: {}", input, e),
  41. }
  42. }
  43. println!("Rust: Process end.");
  44. }

将应用程序编译成 WebAssembly。

$ cd rust_readfile $ cargo build --target wasm32-wasi # 输出文件是 target/wasm32-wasi/debug/rust_readfile.wasm

我们在 Go 程序里面嵌入 WasmEdge 运行 WebAssembly 函数,这个 Go 程序源代码如下。

package main import ( "os" "github.com/second-state/WasmEdge-go/wasmedge" ) func main() { wasmedge.SetLogErrorLevel() var conf = wasmedge.NewConfigure(wasmedge.REFERENCE_TYPES) conf.AddConfig(wasmedge.WASI) var vm = wasmedge.NewVMWithConfig(conf) var wasi = vm.GetImportModule(wasmedge.WASI) wasi.InitWasi( os.Args[1:], // 参数 os.Environ(), // 环境变量 []string{".:."}, // 目录映射 ) // 实例化 wasm。_start 指的是 wasm 程序的 main() 函数 vm.RunWasmFile(os.Args[1], "_start") vm.Release() conf.Release() }

接下来,让我们用 WasmEdge Go SDK 构建 Go 应用程序。

go get github.com/second-state/WasmEdge-go/wasmedge@v0.10.0 go build

运行 Golang 应用程序。

`$ ./read_file rust_readfile/target/wasm32-wasi/debug/rust_readfile.wasm file.txt Rust: Opening input file "file.txt"... Rust: Read input file "file.txt" succeeded. Rust: Please input the line number to print the line of file. # 输入 "5" 然后按下 Enter。 5 #file.txt` 文件的第 5 行内容将被输出: abcDEF_!@#$%^ # 要停止程序,发送 EOF (Ctrl + D)。 ^D # 输出将会打印停止信息: Rust: Process end.

更多的例子可以在 WasmEdge-go-examples GitHub 仓库 中找到。