Компиляция C++ в .wasm файл

224
03 февраля 2020, 05:20

У меня есть следующий C++ код:

#include <emscripten.h>
#include <emscripten/val.h>
#include <stdio.h>
using namespace emscripten;
extern "C" {
    EMSCRIPTEN_KEEPALIVE
    extern void loop() {
        val console = val::global("console");
        console.call<void>("log", std::string("Test"));
    }
}

И у меня есть код JS:

//"bytecode" содержит .wasm файл
const wasmModule = new WebAssembly.Module(bytecode);
const imports = {};
imports.env = {
    __memory_base : 0,
    __table_base : 0,
    memory: new WebAssembly.Memory({ initial: 256 }),
    table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })    
};
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
console.log(wasmInstance.exports);

Как скомпилировать код C++ с помощью Emscripten, чтобы функцию loop было видно из JavaScript?

Я пробовал кучу разных вариаций из разных примеров, но у меня ничего не получилось. (new WebAssembly.Instance возвращает ошибку import object field '__ZdlPv' is not a Function)

EDIT: На данный момент, я использую команду em++ -s WASM=1 -s SIDE_MODULE=1 -std=c++17 -O3 src/Main.cpp -o dest/Main.wasm. Насколько я понял, в importObject'е нужно указывать ряд функций (включая __ZdlPv), но откуда их взять?

Answer 1

Для компиляции кода выполните следующую команду:

emcc src/module.cc -o example.html -s EXPORTED_FUNCTIONS='["_loop"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'

Подключите получившийся .js файл и далее вызывайте функцию через ccall, либо сделайте обертку с помощью cwrap. Я использовал ccall в консоли браузера:

Module.ccal('_loop')

Я пробовал кучу разных вариаций из разных примеров, но у меня ничего не получилось. (new WebAssembly.Instance возвращает ошибку import object field '__ZdlPv' is not a Function)

Похоже, что имена функций у Вас все-таки мангляться. Не вижу необходимости в использовании ключевого слова extern в данном месте (поправьте меня, если это не так):

extern void loop() {
    val console = val::global("console");
    console.call<void>("log", std::string("Test"));
}
READ ALSO
include в C++ для MemoryStatus

include в C++ для MemoryStatus

Как понять какой #include нужно написать для MemoryStatusПотому что MemoryStatus выделяется в коде красным и говорит что идентификатор не определен

235
При запросе QOAuth2AuthorizationCodeFlow::grant появляется ошибка ShellExecute &ldquo;&hellip;&rdquo; failed (error 5)

При запросе QOAuth2AuthorizationCodeFlow::grant появляется ошибка ShellExecute “…” failed (error 5)

После получения настроек для входа через OAuth2 от Google, при попытке отправить запрос на вход через метод grant() появляется ошибка ShellExecute "<ссылка>"...

197
Не могу открыть картинку на localhost (формата jpeg)

Не могу открыть картинку на localhost (формата jpeg)

возник вопрос, написал я такой себе серверЕсли я запрашиваю картинку, то получаю следующее: Чтение для открытия HTML страниц вопросов не вызывает:

212
Выборка элементов в TinyMCE 5

Выборка элементов в TinyMCE 5

коллеги! Целый день бился с данной проблемой, и никак не получается её решитьДокументация TinyMCE, на мой взгляд, уж очень сложна, да еще и на английском

286