Почему библиотека WASM в Rust должна установить тип ящика cdylib? - PullRequest
3 голосов
/ 20 мая 2019

Состояния Rust :

Будет создана динамическая системная библиотека.Это используется при компиляции динамической библиотеки для загрузки с другого языка.Этот тип вывода создает файлы *.so в Linux, файлы *.dylib в macOS и файлы *.dll в 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

1 Ответ

2 голосов
/ 21 мая 2019

Это точно так, как указано в справочнике 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, поэтому он является популярным выбором для интерфейсов сторонних функций.

...