Итак, я выяснил, что они должны были сделать больше шагов, чтобы заставить двоичный файл WASM работать с React, особенно если вы хотите импортировать его в модули React es6 (не из папки publi c).
Я не знаю Не претендуйте на это как на общее решение, только то, которое работает для меня (и, кажется, работает в большинстве случаев).
ФЛАГИ КОМПИЛЕРА
Вот em ++ Команда build, которую я сейчас использую:
em++ ../main.cpp ../stringFormat.cpp \
-Os -g1 \
-s WASM=1 \
-s MALLOC=emmalloc \
-s ALLOW_MEMORY_GROWTH=1 \
-s EXPORT_ES6=1 \
-s MODULARIZE=1 \
-s 'EXPORT_NAME="LongerSubSequence"' \
-s 'ENVIRONMENT="web"' \
--bind \
-o lss.mjs \
-std=c++11 || exit 1
Не уверен насчет всех опций, здесь может быть какая-то оптимизация. Важными из них являются:
- Bind : очевидно, необходимо, чтобы компилятор переопределил искажение имен C ++ при именовании модулей js (по умолчанию компилятор C ++ изменяет все имена переменных вида как реагирует с модулями css).
- EXPORT_ES6 : слегка изменит синтаксис сгенерированного клея js, чтобы его можно было импортировать способом es6.
MODULARIZE : экспортировать все функции под общим модулем (с именем EXPORT_NAME flag), так что вы можете просто импортировать js как модуль и вызывать Module.My_CPP_Function в вашем коде js .
g1 : Сохраняйте сгенерированный код клея достаточно читабельным для управления следующим шагом.
ДОБАВЛЕНИЕ ФАЙЛОВ В REACT
В процессе создаются два файла: lss.m js и lss.wasm. Они go как в дереве проекта React:
My_React_Project
|_public
| |_/path/to/lss.wasm
|
|_src
|_/path/to/lss.mjs
/ path / to / могут быть любым путем внутри папки, даже root.
ADAPT КЛЕЙ JS
Наконец, чтобы исправить ошибки, я отредактировал сгенерированный файл lss.m js:
- Добавить
/* eslint-disable */
вверху файла, во избежание синтаксических ошибок React. - Замените
var _scriptDir = import.meta.url;
на var _scriptDir = '/path/to/lss.wasm';
относительно папки publi c. Не уверен, что это полезно для следующих шагов, но React просто создаст sh с синтаксисом import.meta. - Замените
scriptDirectory = self.location.href;
на scriptDirectory = window.self.location.href;
, поскольку функции React es6 не связаны с window. - Удалите следующий блок:
var dataURIPrefix = "data:application/octet-stream;base64,";
function isDataURI(filename) {
return String.prototype.startsWith ? filename.startsWith(dataURIPrefix) : filename.indexOf(dataURIPrefix) === 0;
}
Он используется компилятором для автоматического определения местоположения двоичного файла, но я обработал его самостоятельно.
заменить
var wasmBinaryFile = "lss.wasm";
на
const wasmBinaryFile = '/path/to/lss.wasm';
('/' будет указывать на папку publi c). Удалить:
if (!isDataURI(wasmBinaryFile)) {
wasmBinaryFile = locateFile(wasmBinaryFile);
}
Удалить:
function getBinary() {
try {
if (wasmBinary) {
return new Uint8Array(wasmBinary);
}
if (readBinary) {
return readBinary(wasmBinaryFile);
} else {
throw "both async and sync fetching of the wasm failed";
}
} catch (err) {
abort(err);
}
}
Заменить функцию
getBinaryPromise()
на следующую:
const getBinaryPromise = () => new Promise((resolve, reject) => {
fetch(wasmBinaryFile, { credentials: 'same-origin' })
.then(
response => {
if (!response['ok']) {
throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
}
return response['arrayBuffer']();
}
)
.then(resolve)
.catch(reject);
});
Несколько строк ниже, замените
if (!wasmBinary && typeof WebAssembly.instantiateStreaming === "function" && !isDataURI(wasmBinaryFile) && typeof fetch === "function")
на
if (!wasmBinary && typeof WebAssembly.instantiateStreaming === "function" && typeof fetch === "function")
Это просто удалит условие isDataURI, так как мы «доверяем» пути, который мы дали нашему двоичному файлу файл.
СЕЙЧАС ИСПОЛЬЗУЙТЕ СВОЙ БИНАРНЫЙ КОД
И это все, что мне понадобилось, чтобы справиться с этим. Теперь в любом из моих реагирующих файлов я могу просто использовать свою функцию c ++ следующим образом:
anyfile. js
import LongerSubSequenceGlue from 'path/to/lss.mjs';
// Avoid main function running if you just want to use another function
const lssModule = LongerSubSequenceGlue({
noInitialRun: true,
noExitRuntime: true
});
//...
lssModule.my_cpp_function(...my_params);
Работает как шарм на Chrome, Firefox и Safari сделают еще тест позже.