Dia*_*nne 3 node.js emscripten webassembly
我有一个 C++ 项目,我已使用 emscripten 将其转换为 javascript。我需要帮助通过节点实现文件输入到程序中。据我了解,emscripten 中的默认文件系统使用只能在网页或网络工作人员上完成的预加载数据。我需要我的在命令行上使用node.js。
查看文档,我发现有一种方法可以使用 NODEFS 而不是默认的 MEMFS,这应该允许我执行此操作。但是,我不确定该怎么做。我不太明白所提供的测试代码。
以下是原始 C++ 项目中文件处理的方式:
void InputFile(std::string &fileName)
{
std::ifstream in(fileName);
if (in.fail())
{
std::cerr << "ERROR, Could not open " << fileName << std::endl;
exit(1);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用文件运行转换后的程序时,node project.js -f test.file我收到错误消息:ERROR, Could not open test.file意味着打开文件失败。原始的 C++ 项目能够打开该文件,没有任何问题,所以我知道文件本身没有问题。
我不确定我必须做什么才能使转换后的项目与文件输入一起工作,任何帮助将非常感激。
使用emscripten构建的WebAssembly模块没有有关物理文件系统中文件的信息。相反,它使用虚拟文件系统。您所要做的就是在物理系统上的文件与模块虚拟系统上的文件之间创建链接。NODEFS为您提供了这个机会。
我们将首先使用嵌入式 JS 代码(使用EM_ASM)在物理和虚拟文件系统之间添加上述链接来修改您的 C++ 代码。首先(1),我们'/temp'在虚拟文件系统上创建一个目录,所有引用的文件都将位于其中。然后(2),我们将这个新的虚拟目录与所有引用的文件所在的真实物理位置(当前工作目录'.')链接已经是了。
#include <emscripten.h>
#include <emscripten/bind.h>
#include <iostream>
#include <fstream>
void InputFile(const std::string &fileName)
{
EM_ASM(
FS.mkdir('/temp'); // (1)
FS.mount(NODEFS, {root : '.'}, '/temp');); // (2)
std::ifstream in(std::string("/temp/") + fileName);
if (in.fail())
{
std::cerr << "ERROR, Could not open " << fileName << std::endl;
exit(1);
}
}
EMSCRIPTEN_BINDINGS(Module)
{
emscripten::function("InputFile", &InputFile);
}
Run Code Online (Sandbox Code Playgroud)
现在,因为在 WebAssembly 模块中,我们使用的是虚拟文件系统,而不是物理文件系统,所以当前目录(根'.')中每个引用的文件实际上位于先前链接的虚拟目录中('/temp')。因此,'/temp'目录位于引用文件的名称之前:std::ifstream in(std::string("/temp/") + fileName);。
最后,我们可以编译这个文件。我们强制同步编译(以确保require按时加载 WASM 模块)。此外,该选项-s EXIT_RUNTIME=1确保 C++ 命令exit(1);完成执行。另外,我们需要链接Embind ( --bind) 和NODEFS ( -lnodefs.js):
emcc project.cpp -o project.js -s WASM_ASYNC_COMPILATION=0 -s EXIT_RUNTIME=1 --bind -lnodefs.js
Run Code Online (Sandbox Code Playgroud)
要使用与您提到的相同的调用约定来测试 WebAssembly 模块,我们可以使用以下test.js脚本:
var Module = require('./project.js');
if (process.argv[3] && process.argv[2] === '-f') {
const filename = process.argv[3];
Module.InputFile(filename);
} else {
console.log('Pass the file with -f flag!');
}
Run Code Online (Sandbox Code Playgroud)
要运行该文件,您所要做的就是:node test.js -f test.file
如果引用的文件位于当前工作目录中,则此方法效果很好。如果不是,您可以修改 的代码InputFile以提取其所在的目录fileName,然后相应地挂载实目录到虚拟目录。
| 归档时间: |
|
| 查看次数: |
1502 次 |
| 最近记录: |