版本区别
截止到目前(2024-06-11)位置,rust 支持的 wasm target 如下:
$ rustup target list | grep wasm
wasm32-unknown-emscripten
wasm32-unknown-unknown
wasm32-wasi
wasm32-wasi-preview1-threads
上述三个版本区别如下:
版本 | 解释 |
---|---|
wasm32-unknown-emscripten | 使用 emscripten 编译生成 wasm,适用于包含 C/C++ 的项目。 |
wasm32-unknown-unknown | 借助 wasm workgroup 编写的标准库来生成面向 wasm 的代码。 |
wasm32-wasi | wasi 是 WebAssembly System Interface 的缩写。旨在通过规定系统接口允许 wasm 运行在超出浏览器的环境下。允许 wasm 运行在主机环境中。 |
Emscripten
rust binary target 使用 wasm32-unknown-emscripten 编译后会同时生成一个 js 文件和一个 wasm 文件。js 文件包含了一些胶水代码用来使用 wasm。下面的代码描述了如何将一个 rust 函数导出到 wasm 中:
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn js_parse_loongdoc(source: *mut c_char) -> *const c_char {
let source = unsafe { CStr::from_ptr(source) }
.to_string_lossy()
.to_string();
let v = match parse_loongdoc(source.as_bytes()) {
Ok(v) => serde_json::to_string(&v).unwrap(),
Err(err) => {
println!("parse failed: {err:?}");
Default::default()
}
};
let res = ManuallyDrop::new(CString::new(v).unwrap());
res.as_ptr()
}
编译时需要添加参数将部分胶水函数导出:
$ EMCC_CFLAGS="-sEXPORTED_RUNTIME_METHODS=ccall,cwrap,cfree" cargo build -F wasm --target=wasm32-unknown-emscripten
然后在 nextjs 中使用:
<Script
src="loongdoc.js"
onLoad={() => {
Module.onRuntimeInitialized = function () {
var parser = Module.cwrap('js_parse_loongdoc', 'string', ['string'])
console.log(parser("= title0"))
}
}}
></Script
|