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

Why must a WASM library in Rust set the crate-type to cdylib?

Rust reference states:

A dynamic system library will be produced. This is used when compiling a dynamic library to be loaded from another language. This output type will create *.so files on Linux, *.dylib files on macOS, and *.dll files on Windows.

我的 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

正如 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 的明显优势,这就是为什么它是外部函数接口的流行选择。