如何使用 WebAssembly 和 JS 将命令行参数传递给 C 代码?

How to pass command line arguments to C code with WebAssembly and JS?

我正在尝试使用 WebAssembly 和纯 JS 在网络上 运行 一些小型 C 演示,并且我正在使用 WASI-SDK/WASI-libc:

编译我的代码

clang --target=wasm32-unknown-wasi --sysroot=<sysroot> -nostartfiles -O3 -flto -Wl,--no-entry -Wl,--export=malloc -Wl,--export-all -Wl,--lto-O3 src.c -o src.wasm

然后我使用 this small JS library 来实现 WASI 功能。这对于使用 stdout 进行打印非常有效,我什至测试过将字符串和其他类型传递给不同的函数。但是我不知道如何将字符串数组作为参数传递给 main

我不想使用 Node 或 Emscripten,这就是我选择最小 JS 实现的原因。

编辑:

为了添加命令行参数,我从编译器调用中删除了 -nostartfiles-Wl,--no-entry,并从 WASI 标准中实现了 args_getargs_sizes_get。从那里开始,就像从 wasm 的导出函数中调用 _start 一样简单。

如果你想使用 WASI,那么将 args 传递给 main 的方法是实现 wasi_snapshot_preview1.args_getwasi_snapshot_preview1.args_sizes_get 系统调用,WASI 程序使用它们来访问 argv 值。在那种情况下,你会想要调用 _start 而不是 main.

如果您想绕过它并直接调用 main,您需要以某种方式在线性内存中分配 char * 指针数组,然后您可以将其作为 argv 值传递。如果您尝试采用这种方法,您面临的问题是很难在调用 main 之前分配内存(例如通过 malloc)。我的建议是使用第一种方法,即调用 _start 并实现访问 argv 所需的 wasi 系统调用。 (您也可以调用,然后从 link 命令中删除 -Wl,--no-entry)。