如何加载存储在子目录中的 .wasm 文件?
How can I load .wasm files stored in a subdirectory?
我正在尝试一个简单的示例来调用编译为 .wasm 的 C 函数 JavaScript。
这是 counter.c
文件:
#include <emscripten.h>
int counter = 100;
EMSCRIPTEN_KEEPALIVE
int count() {
counter += 1;
return counter;
}
我用emcc counter.c -s WASM=1 -o counter.js
编译的。
我的main.js
JavaScript文件:
Module['onRuntimeInitialized'] = onRuntimeInitialized;
const count = Module.cwrap('count ', 'number');
function onRuntimeInitialized() {
console.log(count());
}
我的 index.html
文件只加载正文中的两个 .js 文件,没有别的:
<script type="text/javascript" src="counter.js"></script>
<script type="text/javascript" src="main.js"></script>
它工作正常/将 101 打印到控制台,但是当我将 counter.c
文件移动到 wasm
子目录时 ,使用 emscripten 重新编译它并将 script
标记更新为 src="wasm/counter.js"
,counter.js
脚本尝试从根目录而不是 wasm
子目录加载 counter.wasm
,我收到错误:
counter.js:190 failed to asynchronously prepare wasm: failed to load wasm binary file at 'counter.wasm'
我做了一些研究,但我没有找到任何方法告诉 emscripten 让生成的 .js 文件从同一子目录加载 .wasm。
如果您查看 emscripten 创建的生成的 'loader' 文件,它有一个 integrateWasmJS
函数,如下所示:
function integrateWasmJS(Module) {
var method = Module['wasmJSMethod'] || 'native-wasm';
Module['wasmJSMethod'] = method;
var wasmTextFile = Module['wasmTextFile'] || 'hello.wast';
var wasmBinaryFile = Module['wasmBinaryFile'] || 'hello.wasm';
var asmjsCodeFile = Module['asmjsCodeFile'] || 'hello.temp.asm.js';
...
}
您可以看到 wasmBinaryFile
表示二进制文件的位置。如果未设置,则提供默认值。
看起来您应该能够在您的 main.js
文件中覆盖它,如下所示:
Module['wasmBinaryFile'] = 'wasm/counter.wasm';
正如所解释的,你应该看看emcc编译器(counter.js)生成的integrateWasmJS()函数。该函数的主体最近发生了变化,现在看起来像这样:
function integrateWasmJS() {
...
var wasmBinaryFile = 'counter.wasm';
if (typeof Module['locateFile'] === 'function') {
...
if (!isDataURI(wasmBinaryFile)) {
wasmBinaryFile = Module['locateFile'](wasmBinaryFile);
}
...
}
}
如果是这种情况,那么您应该向全局模块变量添加一个"locateFile" 函数。因此,在您的 HTML 中,您可以在导入 counter.js 文件之前添加以下代码段:
<script>
var Module = {
locateFile: function(s) {
return 'wasm/' + s;
}
};
</script>
我正在尝试一个简单的示例来调用编译为 .wasm 的 C 函数 JavaScript。
这是 counter.c
文件:
#include <emscripten.h>
int counter = 100;
EMSCRIPTEN_KEEPALIVE
int count() {
counter += 1;
return counter;
}
我用emcc counter.c -s WASM=1 -o counter.js
编译的。
我的main.js
JavaScript文件:
Module['onRuntimeInitialized'] = onRuntimeInitialized;
const count = Module.cwrap('count ', 'number');
function onRuntimeInitialized() {
console.log(count());
}
我的 index.html
文件只加载正文中的两个 .js 文件,没有别的:
<script type="text/javascript" src="counter.js"></script>
<script type="text/javascript" src="main.js"></script>
它工作正常/将 101 打印到控制台,但是当我将 counter.c
文件移动到 wasm
子目录时 ,使用 emscripten 重新编译它并将 script
标记更新为 src="wasm/counter.js"
,counter.js
脚本尝试从根目录而不是 wasm
子目录加载 counter.wasm
,我收到错误:
counter.js:190 failed to asynchronously prepare wasm: failed to load wasm binary file at 'counter.wasm'
我做了一些研究,但我没有找到任何方法告诉 emscripten 让生成的 .js 文件从同一子目录加载 .wasm。
如果您查看 emscripten 创建的生成的 'loader' 文件,它有一个 integrateWasmJS
函数,如下所示:
function integrateWasmJS(Module) {
var method = Module['wasmJSMethod'] || 'native-wasm';
Module['wasmJSMethod'] = method;
var wasmTextFile = Module['wasmTextFile'] || 'hello.wast';
var wasmBinaryFile = Module['wasmBinaryFile'] || 'hello.wasm';
var asmjsCodeFile = Module['asmjsCodeFile'] || 'hello.temp.asm.js';
...
}
您可以看到 wasmBinaryFile
表示二进制文件的位置。如果未设置,则提供默认值。
看起来您应该能够在您的 main.js
文件中覆盖它,如下所示:
Module['wasmBinaryFile'] = 'wasm/counter.wasm';
正如
function integrateWasmJS() {
...
var wasmBinaryFile = 'counter.wasm';
if (typeof Module['locateFile'] === 'function') {
...
if (!isDataURI(wasmBinaryFile)) {
wasmBinaryFile = Module['locateFile'](wasmBinaryFile);
}
...
}
}
如果是这种情况,那么您应该向全局模块变量添加一个"locateFile" 函数。因此,在您的 HTML 中,您可以在导入 counter.js 文件之前添加以下代码段:
<script>
var Module = {
locateFile: function(s) {
return 'wasm/' + s;
}
};
</script>