reactjs - 如何使用带有反应的 emscripten wasm?
问题描述
我无法让 emscripten wasm 在反应中工作。
使用 create-react-app 创建一个全新的应用程序
安装了 react-app-rewired 2.1.6 和 wasm-loader 1.3.0
添加了 config-override.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 文件复制到 /src 文件夹
接下来我想利用 wasm 并添加到 App.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 (in promise) 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";
给出错误:
Uncaught (in promise) RuntimeError: abort(CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0) at Error
我玩了很多不同的 emcc 设置,但没有成功。
在简单的 HTML 页面中使用相同的 wasm 文件效果很好
<!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>
我缺少什么让它在反应应用程序中工作?
解决方案
推荐阅读
- python - 使用VS Code按行(f10)运行的jupyter笔记本出现问题
- node.js - 跨级别填充猫鼬并显示某些字段
- python - 如何导入 FastAPI 应用程序文件夹以满足 pycharm 和 pylint?
- python - 使用 numpy 生成具有正态分布的从 0 到 1 的随机十进制数
- laravel - Laravel 和 Nuxtjs cors 显示上传文件的问题
- javascript - JS Amcharts:如何访问 LineX tooltipHTML 适配器索引?
- microcontroller - ESP8266,连接 AP 时,请求特定 IP 或可发现主机名?
- python - 遍历行如何提高速度
- excel - Excel VBA - 打开所有 .csv 文件并使用单元格值另存为 .xlsx
- flutter - 无论设备方向如何,如何在颤动中获取屏幕尺寸