【问题标题】:Write to file within WebAssembly在 WebAssembly 中写入文件
【发布时间】:2019-04-28 01:26:19
【问题描述】:

我有以下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 环境的最佳实践。任何评论将不胜感激。谢谢。

【问题讨论】:

    标签: javascript webassembly wasm-bindgen


    【解决方案1】:

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

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

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

    后续问题:

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

    许多 C 函数在 C 和 JS 中实现一起。其中 C 部分直接链接到 WebAssembly(参见他们的实现 here),JS 部分在 library_*.js 下的 here 下实现。

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

    【讨论】:

    • 感谢您的回答约翰,它有很大帮助。所以只是两个后续问题,shell.js 是否像 write.js emcc 一样被用来生成 JS 代码?另外,假设在浏览器中我以某种方式启用了写入/读取文件系统的功能。这不会导致一些严重的安全问题吗?我知道WebAssembly 有一个沙盒设施,但只要启用文件系统 API,它在任何意义上都会成为安全风险。你能理解这个吗?还是我在这里错过了什么?
    • 直接编辑了我的答案,因为它很长。
    • WASM 不仅适用于浏览器。当不在浏览器上时,对库的读写没有限制。
    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 2016-06-04
    • 2012-01-23
    • 2012-09-26
    相关资源
    最近更新 更多