我正在开发一个Rust程序,希望在运行时,使用WebAssembly作为脚本语言来驱动其行为。我们假设脚本也是用Rust写的。我已经阅读了Wasmer、Wasmtime和Lucet的教程,虽然exportedimported函数可以作为参数并返回WASM基元类型,但似乎没有一个简单无痛的解决方案来在Rust二进制文件和运行在其中的WASM脚本之间传递任意数据。特别是字符串,必须由以下方法处理 手动传递一个基元作为一种指针。 到运行时的线性内存和一个长度。
wasm-bindgen
似乎可以解决我的问题,但它只针对浏览器中的WASM-JS通信。有 *-interface-types
Wasmer和Wasmtime的箱子,但他们没有教程,而且是实验性的,可能会有变化。我不需要通过 struct
的,但我想实现这样的事情。
// in the host program
let argument: &[u8] = &[0, 1... n]; // dumb byte slice
let guest_result: Vec<u8> = wasm_runtime.call("guest_function", &[argument]);
// in the guest WASM library/script
let data_from_host: Vec<u8> = imported_function(some_other_bytes);
只是通过和返回 Vec<u8>
或 &[u8]
两种方式都够了,我可以把它们反序列化,用。bincode
或其他。有人实现过吗?我可以像使用字符串一样共享线性内存,但这似乎不安全,尤其是在多个线程上使用多个脚本时。
tl;dr 我想使用WASM作为脚本语言,并通过 &[u8]
或 Vec<u8>
但没有找到任何简单的方法。
这个可用性问题是已知的,而且似乎正在积极解决。https:/hacks.mozilla.org201908webassembly -interface -types
下面是对该帖中一些结尾说明的跟进。https:/github.combytecodealliancewasmtimeissues677。
我没有什么写C语言或处理syscall接口的经验,所以对我来说传值也很麻烦。大多数情况下,我只是投入时间去构建出更高层次的抽象(就像wasm-bindgen所做的那样),这样我在传递数据的时候就会更加容易。
举个例子,看起来wasi提供了一个你可以实现的接口,而且他们抽象掉了所有繁琐的部分。https:/docs.rscratewasi0.9.0+wasi-snapshot-preview1sourcesrclib_generated.rs。 你可以在这里看到lucet实现它。https:/github.combytecodealliancelucetblobmasterlucet-wasisrcruntime.rs。
我不认为这对你有什么帮助,除非你想实现wasi,但这是一个很好的例子,可以实现你所要的那种抽象。