emscripten:在Node.js中异步调用时,C函数未“就绪”

问题描述 投票:0回答:1

我已经用Emscripten编译了一个C函数,并编写了此JS包装器,该包装器在交互式Node.js shell中可以正常工作:

// script generated by Emscripten
const _smaz = require("./_smaz");

// exported wrapper function
exports.compress = function(str_in) {
  var encoded = encoder.encode(str_in);
  var out_heap = _smaz['_malloc'](encoded.length * 8);
  ...
}

但是,在我的应用程序中立即调用该函数时,_malloc失败:

TypeError: Cannot read property 'apply' of undefined
    at Object.a._malloc

即使添加100ms setTimeout也可以解决问题。看起来像编译的Emscripten东西是异步加载的,功能不能立即使用。

处理此问题的正确方法是什么? Emscripten docs建议在加载“页面”后添加Module['onRuntimeInitialized']函数,但是我不确定在服务器端Node.js应用中应该将其放置在什么位置,或者不确定它是否完全适用。

这是我的编译方式:

emcc smaz.c -O2 -o _smaz.js --closure 1 -s EXPORTED_FUNCTIONS="['_smaz_compress', '_smaz_decompress']" -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]'
javascript node.js emscripten
1个回答
0
投票

结果是有两个emcc编译器选项可禁用异步启动/加载行为:-s BINARYEN_ASYNC_COMPILATION=0-s SINGLE_FILE=1。这为我解决了问题。

从相关的GitHub issue

一般来说,emscripten尝试为wasm异步启动,因为这是浏览器可以最优化的地方,更糟糕的是,Chrome当前对同步编译的大小有限制(希望很快会修复)。但是您可以强制进行同步编译用-s BINARYEN_ASYNC_COMPILATION=0

这仍然需要获取wasm二进制文件。默认情况下,我们获取它是异步的,但是如果您有办法自己获得它,您可以在Module['wasmBinary']上进行设置,我们将仅使用它同步地。或者,#5296将添加一个嵌入选项文件,使其同步可用。

© www.soinside.com 2019 - 2024. All rights reserved.