我试图在一个react项目中加载一个简单的web组装模块。这个wasm模块是用 MODULARIZE
选项。
从 文件 我试着将其纳入我的代码中,如下所示。
fetch('./my-library.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(results => {
console.log("do something");
});
理想的情况是,我想把结果存储在... state
这样我就可以在整个代码中访问该模块(替换控制台日志)。
不幸的是,这给了我一个错误
Unhandled Rejection (CompileError): wasm validation error: at offset 4: failed to match magic number
我错过了什么?编译没有 MODULARIZE
也给出了这个错误。
要使用 .wasm
目前在任何浏览器中,你必须将其托管在任何简单的服务器上,并使用适当的MIME Content-Type,例如在chrome网络标签中,你必须看到这样的响应。
那么,只有在你的WASM中作为适当的反应来对待。fetch('./my-library.wasm')
编码
您可以参考官方文件 稿件
明言
不幸的是,一些浏览器(包括Chrome、Safari和Internet Explorer)不支持file:/ XHR请求,并且不能加载HTML所需的额外文件(如.wasm文件,或下面提到的打包文件数据)。对于这些浏览器,你需要使用web服务器来提供文件。最简单的方法是使用python的SimpleHTTPServer(在当前目录下执行python -m SimpleHTTPServer 8080,然后打开 http:/localhost:8080hello.html。).
我可以看到你使用的是react,所以很明显你使用的是本地的Node.JS服务器,你需要把二进制文件和非动态内容放在一起,而这些内容不应该是 ./
......它应该是其他文件夹,在那里 .css
和 images
有
重要提示。 它是强制性的,响应必须有 application/wasm
我试过了 这个 和 这个 与我的模块,但他们没有工作,所以尝试将wasm文件直接放在公共文件夹中,并从那里获取它(也可以看到。这个). 它需要根据wasm模块的使用情况进行一些调整(内存设置等)。我的具体案例现在是这样的
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
});
}
编辑
由于react的路由问题,当我从javascript包装器(例如a.out.js)中获取wasm时,我收到了魔法数字错误。最后,我决定把javascript作为一个依赖项包含在index.html文件中,这样就不会那么麻烦了。这样做的好处是,不用和webpack打交道,webpack也不会和emcc生成的js打交道。另外,不直接加载wasm模块,emcc-generated js会负责设置wasm模块。importObject
.