Ske*_*nxf 7 javascript rust webassembly wasm-bindgen
我正在尝试弄清楚如何使用 Rust 和 wasm-bindgen 调用 JavaScript 函数。由于缺乏浏览器支持,我无法将 wasm-bindgen 与 ES6 模块与 Web Worker 一起使用。
据我所知,声明存在一个 JavaScript 函数供我在 Rust 端调用是很简单的
#[wasm_bindgen]
extern {
fn logProgress(percent: f64);
}
Run Code Online (Sandbox Code Playgroud)
但是我不知道在哪里定义 JavaScript 实现。如果我尝试从 JavaScript 调用 Rust 函数来调用 undefined,logProgress那么我会收到运行时错误:Error: logProgress is not defined
我可以从 wasm-bindgen 文档中看到,如果我将 wasm-bindgen 与 ES6 模块一起使用,那么我可以将 rust 代码更改为
#[wasm_bindgen(module = "/progress.js")]
extern {
fn logProgress(percent: f64);
}
Run Code Online (Sandbox Code Playgroud)
并在中声明 JavaScript 函数progress.js
export function logProgress(percent) {
console.log(percent)
// actual implementation would not just log
}
Run Code Online (Sandbox Code Playgroud)
由于我是通过全局导入 Rust API wasm_bindgen,所以我想我应该能够在 Web Worker 中的同一部分周围定义实现,但我搜索了很多文档,但找不到任何关于如何做这个。
importScripts('foo_wasm.js')
wasm_bindgen('foo_wasm_bg.wasm').then(fooWasmModule => {
memory = fooWasmModule.memory
const { Foo, Bar, Baz, foobar } = wasm_bindgen;
// JS has 'imported' the Rust structs and functions
// How to 'export' the JS functions to Rust?
}
Run Code Online (Sandbox Code Playgroud)
由@eggyal 评论指导。wasm-bindgen在板条箱内提供了一个WorkerGlobalScope类型web-sys,但是,您不能使用它,因为它不具有您在自己的工作线程中定义的函数。
因此,您想要做的是依靠ducktyping。您定义自己的WorkerGlobalScope类型,然后将导入视为对象的方法。
#[wasm_bindgen]
extern "C" {
type WorkerGlobalScope;
#[wasm_bindgen(method)]
fn logProgress(this: &WorkerGlobalScope, percent: f64);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
#[wasm_bindgen]
pub fn call_from_worker() {
let global = js_sys::global().dyn_into::<WorkerGlobalScope>();
if let Ok(worker) = global {
worker.logProgress(99.9);
}
}
Run Code Online (Sandbox Code Playgroud)
缺点是,如果您尝试在工作线程之外使用它,转换将会失败。
| 归档时间: |
|
| 查看次数: |
1696 次 |
| 最近记录: |