如何加载存储在子目录中的 .wasm 文件?

Posted

技术标签:

【中文标题】如何加载存储在子目录中的 .wasm 文件?【英文标题】:How can I load .wasm files stored in a subdirectory? 【发布时间】:2017-09-20 22:31:43 【问题描述】:

我正在尝试使用 javascript 调用编译为 .wasm 的 C 函数的简单示例。

这是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 标记更新为 @987654331 @,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。

【问题讨论】:

【参考方案1】:

正如ColinE in the other answer 所解释的,您应该查看由emcc 编译器(counter.js)生成的integrateWasmJS() 函数。该函数的主体最近发生了变化,现在看起来像这样:

function integrateWasmJS() 
    ...
    var wasmBinaryFile = 'counter.wasm';

    if (typeof Module['locateFile'] === 'function') 
        ...
        if (!isDataURI(wasmBinaryFile)) 
          wasmBinaryFile = Module['locateFile'](wasmBinaryFile);
        
        ...
    

如果是这种情况,那么您应该在全局 Module 变量中添加一个“locateFile”函数。因此,在您的 HTML 中,您可以在导入 counter.js 文件之前添加以下 sn-p:

<script>
  var Module = 
    locateFile: function(s) 
      return 'wasm/' + s;
    
  ;
</script> 

【讨论】:

【参考方案2】:

如果您查看 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';

【讨论】:

以上是关于如何加载存储在子目录中的 .wasm 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中提供 WASM 文件

未解决:fatal error: wasm.h: 没有那个文件或目录 #include <wasm.h>

svnadmin 加载到现有目录?

使用 wasm 将模块导入并编译到 webpack 中

如何仅将目录下许多子目录中的文件复制到 GCP 中的另一个项目存储桶中?

如何在 Databricks 中迭代以读取存储在数据湖不同子目录中的数百个文件?