Как использовать emscripten wasm с react? - PullRequest
0 голосов
/ 04 августа 2020

Я не могу заставить emscripten wasm работать в React.

  • Создайте приложение fre sh с помощью create-react-app

  • установлено приложение react-app-rewired 2.1.6 и wasm-loader 1.3.0

  • добавлено переопределение конфигурации. js с

    const path = require("path");
    
    module.exports = function override(config, env) {
      const wasmExtensionRegExp = /\.wasm$/;
    
      config.resolve.extensions.push(".wasm");
    
      config.module.rules.forEach((rule) => {
        (rule.oneOf || []).forEach((oneOf) => {
          if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
            // make file-loader ignore WASM files
            oneOf.exclude.push(wasmExtensionRegExp);
          }
        });
      });
    
      // add a dedicated loader for WASM
      config.module.rules.push({
        test: wasmExtensionRegExp,
        include: path.resolve(__dirname, "src"),
        use: [{ loader: require.resolve("wasm-loader"), options: {} }],
        type: "javascript/auto",
      });
    
      return config;
    };
    

Скомпилировал код c с помощью:

emcc src\emsample.c -s WASM=1 -o deploy\www\emsample.js -s "EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']" -s EXPORTED_FUNCTIONS="['_sayHi', '_myFunction', '_daysInWeek', '_int_sqrt', '_main']" -s MODULARIZE -s EXPORT_NAME=EmSample -s 

Скопировал wasm и js файл в / sr c папку

Затем я хотел использовать wasm и добавлен в приложение. js:

[...]
import EmSample from "./emsample";

EmSample({
  global: {},
  env: {
    memoryBase: 0,
    tableBase: 0,
    memory: new WebAssembly.Memory({ initial: 256 }),
    table: new WebAssembly.Table({ initial: 0, element: "anyfunc" }),
  },
}).then((instance) => {
  // What is with the weird exports._Z4facti function?
  // This is how the function name is encoded by the C++ to wasm compiler
  const sayHi = instance.exports._myFunction;

  console.log(sayHi());
});
[...]

Что дает ошибку:

Uncaught (в обещании) TypeError: WebAssembly.instantiate (): Import # 0 module = "wasi_snapshot_preview1" ошибка: модуль не является объектом или функцией

Если я изменяю оператор импорта на

//Remark: add /*eslint-disable*/ to emsample.js to avoid problems with eslint
import EmSample from "./emsample.js";

, выдает ошибку:

Непойманный (в обещании) RuntimeError: abort (CompileError: WebAssembly.instantiate (): ожидаемый magi c word 00 61 73 6d, найдено 3 c 21 44 4f @ + 0) при ошибке

Я поигрался с большим количеством различий ferent em cc безуспешно.

Использование того же файла wasm на простой HTML странице работает хорошо

<!DOCTYPE html>
<title>Emscripten + npm example</title>
Open the console to see the output from the wasm module.
<script type="module">
  import EmSample from "./emsample.js";

  EmSample().then(function (mymod) {
    console.log(mymod._sayHi());
    const mySqrt = mymod.cwrap("int_sqrt", "number", ["number"]);
    console.log(mySqrt(64));
    console.log(mySqrt(7));
    console.log(mySqrt(8));
    console.log(mymod._myFunction());
    console.log(mymod._daysInWeek());
  });
</script>

Что мне не хватает, чтобы заставить его работать в реакции приложение?

...