我有一个C++程序,它接受两个文件作为输入,并生成一个文件作为输出。这些文件包含字符串。我使用带有以下标志的Emscripten成功地将此程序编译为webassembly:
emcc program.bc -o program.js -s USE_ZLIB=1 -s EXPORTED_RUNTIME_METHODS="['FS', 'callMain']" -s ALLOW_MEMORY_GROWTH=1 -s ENVIRONMENT='web, worker'
然后,我使用以下粘合代码将字符串(作为参数传递(写入Emscripten虚拟文件系统中的文件。然后使用这些文件来运行program
的主要功能。然后从文件系统读取输出文件,并将其内容记录到控制台:
const Module = require('./program.js')
async function main(input1, input2){
Module.FS.writeFile('first_input.txt', input1)
Module.FS.writeFile('second_input.txt', input2)
Module.callMain(['-r', 'first_input.txt', '-q', 'second_input.txt', '-o', 'test.out', '-t', '1'])
const output = Module.FS.readFile('test.out', { encoding: 'utf8' })
console.log(output)
}
module.exports = main
当尝试调用上述主函数时,我得到错误:
Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'writeFile')
当Iconsole.log(Module.FS)
时,它确实是未定义的。此外,console.log(Module)
返回空对象{}
。在program.js
中,FS模块似乎是通过Module["FS"] = FS
启用的。当我为节点环境(使用-s ENVIRONMENT='node'
(编译它时,它可以顺利工作。
为什么它对工人环境不起作用?我能做些什么来修复它?
编辑:我试图将代码包装在"onRuntimeInitialized"函数中,但我得到了相同的错误:
const Module = require('./program.js')
async function main(input1, input2){
Module.onRuntimeInitialized = () => {
Module.FS.writeFile('first_input.txt', input1)
Module.FS.writeFile('second_input.txt', input2)
Module.callMain(['-r', 'first_input.txt', '-q', 'second_input.txt', '-o', 'test.out', '-t', '1'])
const output = Module.FS.readFile('test.out', { encoding: 'utf8' })
console.log(output)
}
await Module.onRuntimeInitialized()
}
module.exports = main
EDIT2:上面的主函数实际上是在worker上运行的,而不是在HTML文档中的脚本标记内部。我不能直接编辑HTML文档,这就是我require
Emscripten输出JavaScript文件的原因。
解决方案是:
- 使用
MODULARIZE=1
标志编译程序
emcc program.bc -o program.js -s USE_ZLIB=1 -s EXPORTED_RUNTIME_METHODS="['FS', 'callMain']" -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s EXPORT_NAME='createModule'
- 导入模块,然后等待生成的promise
import createModule from './program.js'
async function main(input1, input2){
const Module = await createModule()
Module.FS.writeFile('first_input.txt', input1)
Module.FS.writeFile('second_input.txt', input2)
Module.callMain(['-r', 'first_input.txt', '-q', 'second_input.txt', '-o', 'test.out', '-t', '1'])
const output = Module.FS.readFile('test.out', { encoding: 'utf8' })
console.log(output)
}
export default main