Почему библиотека WASM в Rust должна устанавливать тип контейнера как cdylib?

Эталонные состояния ржавчины:

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
}

Груз.томл

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

[dependencies]

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

индекс.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
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
8
0
859
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это точно так, как указано в справочнике 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-функция? Вызовы функций могут отличаться от языка к языку. Путем искажения, порядка аргументов в стеке вызовов и т. д. Это называется АБИ. C имеет явное преимущество наличия определенного и стабильного ABI, поэтому он является популярным выбором для внешних функциональных интерфейсов.

Любые документы о том, что делает динамическую библиотеку «динамической»? Извините за невежество :(

Armeen Harwood 21.05.2019 18:52

Я думаю, что невежество нормально на сайте, специально созданном для того, чтобы задавать вопросы ;-). К сожалению, я не могу вспомнить ни одной ссылки, указывающей точные различия между статическими и динамическими библиотеками. В верхней части моей шляпы я могу думать о двух вещах: во-первых: динамические библиотеки должны быть скомпилированы с независимым от позиции кодом, хотя в настоящее время это также используется по умолчанию для статических библиотек. Во-вторых: динамические библиотеки предоставляют функцию инициализации, которая вызывается после их загрузки. Обычно это используется для инициализации их глобальных символов.

Markus Klein 22.05.2019 17:32

Другие вопросы по теме

Похожие вопросы

Могу ли я десериализовать векторы с префиксом переменной длины с помощью Bincode?
Возврат замыкания из замыкания в качестве возвращаемого значения для функции
Сообщает ли компилятору, возвращающему тип со значением 'static, что это значение не имеет связанного времени жизни, или оно делает это значение статическим?
Как я могу реализовать сложные макросы, такие как `format_args!`, в пользовательском пространстве?
Простая реализация для получения итератора первого слова каждой строки ввода
Как кросс-компилировать код Rust для Raspberry Pi Zero W
Передача String::as_str в Option<String>::map() не компилируется с ошибкой несоответствия типов
Можно ли выполнить деструктурирование присваивания с аннотациями типов?
Как сделать, чтобы мой пользовательский производный макрос принимал общие параметры трейта?
Как я могу десериализовать поле bincode без заданной длины