使用wasm-pack进行构建时,在Rust和JavaScript之间传递字符串

时间:2020-03-02 20:18:02

标签: rust webassembly rust-cargo wasm-bindgen wasm-pack

我正在构建Chrome扩展程序,因此我选择使用某些WebAssembly功能。我使用wasm-pack来构建源代码,因为它提供了--target web,可以降低Wasm函数插入的复杂性。在Rust和JS之间传递整数值可以无缝地进行,但是我似乎无法将字符串传递给Rust,反之亦然。

这是我正在使用的东西:

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);

    #[wasm_bindgen(js_namespace = console)]
    fn log(x: &str);
} 

#[wasm_bindgen]
pub extern "C" fn add_two(x: i32) -> i32 {
   x + 2
}

#[wasm_bindgen]
pub fn hello(name: &str) {
    log("Hello") // <-- passing a '&str' directly works. I can see it in the browser.
    log(name) // <-- does not seem to work. There is no output
    alert(&format!("Hello {}", name)); // <- Only output im getting is "Hello !"
}

更新:有关如何导入和实例化wasm的更多信息

使用wasm-pack构建并将导入的pkg目录导入我的JS文件夹后。我通过manifest.json文件以web_resource的形式将pkg目录的内容提供给项目。

这是我如何在content_script.js中加载脚本

(async function() {
  // Get the JS File
  const src = await import("/pkg/rusty.js");
  // Fetch the wasm file.
  const wasm_src = chrome.extension.getURL("/pkg/rusty_bg.wasm");
  //src has an exported function 'default' that initializes the WebAssembly module.
  let wasm = await src.default(wasm_src);

  wasm.hello("stack-overflow");
})();

我还注意到,我生成的wasm_bg文件的底部输出了一些Rust错误。 Error output in wasm_bg

1 个答案:

答案 0 :(得分:2)

问题在于您如何加载代码:

(async function() {
  // Get the JS File
  const src = await import("/pkg/rusty.js");
  // Fetch the wasm file.
  const wasm_src = chrome.extension.getURL("/pkg/rusty_bg.wasm");
  //src has an exported function 'default' that initializes the WebAssembly module.
  let wasm = await src.default(wasm_src);

  wasm.hello("stack-overflow");
})();
wasm返回的

.default(...)是具有原始WebAssembly导出功能的对象,只能导出原始数字。

在这种情况下,发生的情况是wasm.hello期望两个整数-WebAssembly内存中字符串的指针和长度-JavaScript高兴地将"stack-overflow"转换为0并提供另一个{{ 1}}作为默认值,这就是为什么您在Rust端最后得到一个空字符串的原因。

您想要的是函数的包装版本,该版本负责适当的转换。这些直接存在于0文件的导入中:

.js