为什么Rust中的WASM库必须将crate-type设置为cdylib?

时间:2019-05-20 20:30:19

标签: rust rust-cargo

Rust reference states

  

将生成一个动态系统库。在编译要从另一种语言加载的动态库时使用。此输出类型将在Linux上创建*.so文件,在macOS上创建*.dylib文件,在Windows上创建*.dll文件。

我的WASM不是*.dylib*.dll*.so ...为什么将板条箱类型设置为cdylib?幕后到底发生了什么?

lib.rs

#[no_mangle]
pub extern fn add_one(x: u32) -> u32 {
    x + 1
}

Cargo.toml

[package]
name = "utils"
version = "0.1.0"
authors = [""]
edition = "2018"

[dependencies]

[lib]
crate-type = ["cdylib"] // Why is this needed

index.html:

<!DOCTYPE html>
<html>
  <head>
    <script> 
      fetch("utils.gc.wasm")
        .then(response => response.arrayBuffer())
        .then(result => WebAssembly.instantiate(result))
        .then(wasmModule => {
          const result = wasmModule.instance.exports.add_one(2);
          const text = document.createTextNode(result);
          document.body.appendChild(text);
        });
    </script>
  <head>
  <body></body>
<html>

端子:

$ cd utils
$ cargo build --target wasm32-unknown-unknown --release
$ wasm-gc target/wasm32-unknown-unknown/release/utils.wasm -o utils.gc.wasm
$ http

1 个答案:

答案 0 :(得分:2)

这完全与Rust参考所指出的一样:我们正在创建一个动态库,以从另一种语言加载。那么为什么输出既不.dll.so也不.dylib呢?那是因为我们没有针对Windows,Linux或MacOS进行编译。我们正在为wasm32-unknown-unknown进行编译。因此,这里参考文献的唯一缺点是没有列出所有可能的平台及其动态库文件结尾。

我们需要一个动态库,因为动态库可以在运行时加载(通常由浏览器加载)。 Rust库必须静态链接才能使用。

关于幕后情况的额外信息:

如果您调用wasm_bindgen宏,它将(除其他外)将函数的签名扩展为C函数。

#[wasm_bindgen]
pub fn my_function() 
#[export_name = "my_function"]
pub extern "C" fn __wasm_bindgen_my_function()

为什么要使用C函数?函数调用因语言而异。通过重整,调用栈上的参数顺序等。这称为ABI。 C具有定义和稳定的ABI的显着优势,这就是为什么它是外来函数接口的流行选择。