如何检测 Emscripten 生成的 .js 何时完成加载 wasm,以便我可以运行调用它的 JS 函数?

Roc*_*icv 5 javascript emscripten webassembly

我正在使用 Emscripten 将一些 C 代码编译为 WebAssembly。这是我的 Makefile 中的最后一个 emcc 调用:

emcc $(CFLAGS) iva.a -o iva.js
Run Code Online (Sandbox Code Playgroud)

它按预期工作并生成 .js 文件和 .wasm 文件。JS 加载到我的 HTML 页面中,如下所示:

<script src="../dist/iva.js">
Run Code Online (Sandbox Code Playgroud)

它会正确加载并实例化 WebAssembly 代码iva.wasm。加载页面后不久,此消息就会出现在控制台中:

Fetch finished loading: GET "http://localhost:6931/dist/iva.wasm".
Run Code Online (Sandbox Code Playgroud)

我认为这意味着我的 WebAssembly 是通过 fetch() 加载的,也许在等待一些处理时,我可以通过控制台访问我的函数:

Module._init_display_system()
Run Code Online (Sandbox Code Playgroud)

并获取返回值。这是正确的并且一切正常。

显然,我也应该能够通过脚本来做到这一点。但是,我看不到一种仅在实例化 WebAssembly后运行函数的方法。我感觉我错过了一些相当明显的东西。

无论如何,我该怎么做?

Sud*_*amy 10

使用Module['onRuntimeInitialized']

Module['onRuntimeInitialized'] = function() {
       console.log("wasm loaded ");
       var x=Module.ccall("doubleIt","number",["number"],[20]);
       alert(x);
    }
Run Code Online (Sandbox Code Playgroud)

你用过emsdk,还有像Wasmfiddle这样的在线WASM编译器。查找我的 github 存储库对这两种方法都有用。


sta*_*tor 7

虽然Sudhakar RSAnil8753的两个解决方案完全没问题,但我想补充一点,您必须在加载 WebAssembly之前执行此方法。否则可能来不及赶上活动了。

除此之外,还有另一种方法,即使用 Promise。如果你添加

-s MODULARIZE=1 -s 'EXPORT_NAME="createMyModule"'
Run Code Online (Sandbox Code Playgroud)

作为编译时的选项emcc,您的结果.js将包含该函数createMyModulePromise一旦您的 WebAssembly 代码可供使用,此函数将返回一个解析值。用法示例:

在 HTML 中,像之前一样添加 WebAssembly:

<script src="../dist/iva.js">
Run Code Online (Sandbox Code Playgroud)

在你的 js 中,调用该函数,在承诺解决后,你就可以开始了:

createMyModule().then(MyModule => {
  console.log('WebAssembly loaded!');
  // Access your functions (if bound by Embind):
  console.log(MyModule.getSomething());
});
Run Code Online (Sandbox Code Playgroud)