emscripten: C функции не «готовы» при асинхронном вызове в Node.js - PullRequest
0 голосов
/ 29 апреля 2020

Я скомпилировал библиотеку C с Emscripten и написал JS, которая правильно взаимодействует с ней в интерактивной оболочке Node.js:

// script compiled by Emscripten
const _smaz = require("./_smaz");
var out_heap = _smaz['_malloc'](encoded.length * 8);
...

Однако _malloc завершается неудачно, когда Функция вызывается непосредственно в моем приложении:

TypeError: Cannot read property 'apply' of undefined
    at Object.a._malloc

Даже добавление 100ms setTimeout решает проблему. Похоже, что скомпилированный Emscripten загружается асинхронно и функции не могут быть использованы немедленно.

Какой правильный способ справиться с этим? Emscripten docs предлагает добавить функцию Module['onRuntimeInitialized'] после загрузки моей "страницы", но я не уверен, где это должно go в серверном приложении Node.js или применяется ли оно в все.

Вот как я собираю:

emcc smaz.c -O2 -o _smaz.js --closure 1 -s EXPORTED_FUNCTIONS="['_smaz_compress', '_smaz_decompress']" -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]'

1 Ответ

0 голосов
/ 30 апреля 2020

Оказывается, есть два параметра компилятора emcc для отключения асинхронного запуска / загрузки: -s BINARYEN_ASYNC_COMPILATION=0 и -s SINGLE_FILE=1. Это решает проблему для меня.

Из связанной проблемы GitHub :

В общем случае emscripten пытается выполнить запуск асинхронно для wasm, потому что это то, что браузеры могут Лучшая оптимизация и, что еще хуже, Chrome в настоящее время имеет ограничение на размер синхронных компиляций (надеюсь, это будет исправлено в ближайшее время). Но вы можете принудительно выполнить компиляцию syn c с помощью -s BINARYEN_ASYNC_COMPILATION=0.

Это все равно оставляет выборку двоичного файла wasm. По умолчанию мы получаем его асинхронно, но если у вас есть способ получить его самостоятельно, вы можете установить его на Module['wasmBinary'], и мы просто будем использовать его синхронно. В качестве альтернативы, # 5296 добавит возможность вставлять этот файл, делая его доступным синхронно.

...