WASM react module parse failed: magic header not detected

烂漫一生 提交于 2021-01-28 05:02:19

问题


I'm trying to load a simple web assembly module in a react project. The wasm module was compiled with the MODULARIZE option.

From the documentation I've tried incorporating this into my code as follows:

fetch('./my-library.wasm')
  .then(response => response.arrayBuffer())
  .then(bytes => WebAssembly.instantiate(bytes))
  .then(results => {
    console.log("do something");
  });

Where ideally I would like to store the results in the state so I can access the module throughout the code (replacing the console log).

Unfortunately this gives me the error

Unhandled Rejection (CompileError): wasm validation error: at offset 4: failed to match magic number

What am I missing? Compiling without MODULARIZE also gives this error.


回答1:


To use .wasm in any browser as of now, you must host it in any simple server with proper MIME Content-Type, For Example in chrome network tab you must see this kind of response

Then only the WASM treated as a proper response in your fetch('./my-library.wasm') code

You can refer the official documentation Emscripten

it clearly says

Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// XHR requests, and can’t load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers you’ll need to serve the files using a webserver. The easiest way to do this is to use the python SimpleHTTPServer (in the current directory do python -m SimpleHTTPServer 8080 and then open http://localhost:8080/hello.html).

I can see you are using react, so obviously you do use a local Node.JS server, you need to put the binary along with non-dynamic content which should not be ./. it should be some other folder where .css and images are there

Important Note: it is mandatory that the response must have application/wasm




回答2:


I tried this and this with my module but they didn't work so tried putting the wasm file directly in the public folder and fetching it from there (see also: this). It needed some tweaking specific to the use-case of the wasm module (memory settings, etc). My specific case looks like this now

componentDidMount() {
  this.loadWasm();
}

loadWasm() {
  const path = process.env.PUBLIC_URL + '/my-library.wasm';
  const importObject = {
    env: {
      memoryBase: 0,
      tableBase: 0,
      memory: new WebAssembly.Memory({initial: 256, maximum: 1024}),
      table: new WebAssembly.Table({initial: 256, element: 'anyfunc'}),
      __assert_fail: function() {
        // todo
      },
      emscripten_resize_heap: function() {
        // todo
      },
      emscripten_memcpy_big: function() {
        // todo
      },
      setTempRet0: function() {
        // todo
      }
    }
  };
  WebAssembly.instantiateStreaming(fetch(path), importObject).then(obj => {
    // do stuff
  });
}

EDIT

I was getting the magic number error when fetching the wasm from its javascript wrapper (e.g. a.out.js) because of a routing problem with react. At the end of it all I decided it was less of a hassle to just include the javascript as a dependency in the index.html file. This has the advantage of not having to mess with webpack and webpack non messing with the emcc-generated js. Also, not loading the wasm module directly, the emcc-generated js takes care of setting the importObject.



来源:https://stackoverflow.com/questions/61478832/wasm-react-module-parse-failed-magic-header-not-detected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!