使用 Emscripten 读写字符串到虚拟文件系统
Read and write string to virtual file system using Emscripten
我有一个 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')
当我console.log(Module.FS)
时,确实是undefined。此外,console.log(Module)
returns {}
,一个空对象。在 program.js
中,似乎确实通过 Module["FS"] = 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:上面的 main 函数实际上是 运行ning 在一个 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
我有一个 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')
当我console.log(Module.FS)
时,确实是undefined。此外,console.log(Module)
returns {}
,一个空对象。在 program.js
中,似乎确实通过 Module["FS"] = 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:上面的 main 函数实际上是 运行ning 在一个 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