2

我有以下一段C代码要编译成WebAssembly.

# include <stdio.h>

int main() {

FILE *f = fopen("file.txt", "w");
if (f == NULL)
{
            printf("Error opening file!\n");
            return 0;
}

/* print some text */
const char *text = "Write this to the file";
fprintf(f, "Some text: %s\n", text);

/* print integers and floats */
int i = 1;
float py = 3.1415927;
fprintf(f, "Integer: %d, float: %f\n", i, py);

char c = 'A';
fprintf(f, "A character: %c\n", c);

fclose(f);

return 0;

}

所以我使用下面的命令来生成一个wasm文件和对应的js文件:

emcc write.c -s WASM=1 -o write.html

但是,当我尝试使用 JS 引擎(如v8)来执行这段代码时,我根本找不到生成的输出。我也没有收到任何错误:

➜  test_code ~/v8/v8/out/x64.release/d8 write.js
➜  test_code 

所以根据我的理解,wasm代码需要利用JS一些与系统相关的功能,比如 I/O 相关的操作符。也许不允许在这个浏览器环境中“操纵”文件系统?因为通常浏览器内部发生的事情应该留在浏览器中。

所以我写信询问将文件 I/O 相关的 C 程序迁移到WebAssembly环境中的最佳实践。任何评论将不胜感激。谢谢。

4

1 回答 1

1

d8确实具有用于 I/O 写入的write功能 ( v8/src/d8.cc?l=1706shell.js ),但 Emscripten从未将其用于简单的 JS shell。如果你想让 Emscripten 的代码在简单的 JS shell 中工作,你需要对它进行一些修改。尝试探索emscripten/src/library_fs.js

编辑:刚刚意识到 d8 的write功能只打印到stdout,所以它不是你想要的。看起来从简单的 JS shell 写入文件是不可能的(它们仅供 JS 引擎开发人员测试东西)。

我没有验证这一点,但我认为在 Node.js 中运行测试代码时,I/O 写入可能会开箱即用。

后续问题:

Emscripten 通过预处理和连接shell.js,preamble.js以及postamble.js在编译时从emscripten.py和生成的一些代码来生成 JS 包装器代码compiler.js。JS代码的预处理使用C风格的预处理器(#if, #else)加上一些{{{ }}},这就是Emscripten的JS代码看起来很有趣的原因。

许多 C 函数是用 C 和 JS一起实现的。它的 C 部分直接链接到 WebAssembly(参见它们的实现在这里),它的 JS 部分library_*.js这里实现。

目前,Chrome 是唯一具有Web FileSystem API的浏览器。Google 和 Mozilla 目前正致力于标准化Writable Files API。大多数人的第一反应是“这是个坏主意”,但由于浏览器已经允许在用户系统(在沙箱中)执行不受信任的代码,因此写入文件可能不是浏览器可以做的最危险的事情(https:// twitter.com/ericlaw/status/1066149633855053825)。

于 2018-11-26T14:45:15.123 回答