我用Emscripten编译了一个C库,并编写了JS,它可以在交互式Node.JS shell中正确地与之交互:
// script compiled by Emscripten
const _smaz = require("./_smaz");
var out_heap = _smaz['_malloc'](encoded.length * 8);
...
然而,当在我的应用程序中立即调用函数时,_malloc
失败:
TypeError: Cannot read property 'apply' of undefined
at Object.a._malloc
甚至添加100ms的setTimeout
也解决了这个问题。看起来编译后的Emscripten内容是异步加载的,并且不能立即使用函数。
处理这个问题的正确方法是什么?Emscripten文档建议在我的"页面"加载后添加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"]'
原来有两个emcc
编译器选项可以禁用异步启动/加载行为:-s BINARYEN_ASYNC_COMPILATION=0
和-s SINGLE_FILE=1
。这为我解决了问题。
来自相关的GitHub问题:
通常,emscripten尝试为wasm异步启动,因为这是浏览器最能优化的,更糟糕的是,Chrome目前对同步编译的大小有限制(希望很快就能修复(。但是您可以强制同步编译用CCD_ 7。
仍然需要获取wasm二进制文件。默认情况下,我们获取它是异步的,但如果你以前有办法自己获得它,你可以在
Module['wasmBinary']
上设置它,我们只使用它同步地。或者,#5296将添加一个选项来嵌入文件,使其同步可用。