最近,我试着用尽可能少的助手来尝试使用组件。
因此,我创建了一个c项目,包含了一些库(stb_image.h)并试图编译它。
下面是一个可复制的简短示例:
#include <emscripten.h>
#define STBI_NO_STDIO
#define STBI_NO_FAILURE_STRINGS
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
EMSCRIPTEN_KEEPALIVE
void test(){
stbi_load_from_memory(NULL, 0, NULL, NULL, NULL, 0);
}下面是我使用的命令:
emcc converter.c -s STANDALONE_WASM -o converter.wasm --no-entry
这很好,给了我一个有效的wasm文件。
但随后,我尝试在浏览器中实例化它,并使用javascript,没有其他任何内容:
let wasm = await Webassembly.instantiateStreaming(fetch('converter.wasm'), {});但我知道这个错误:
Uncaught (承诺) TypeError: WebAssembly.instantiate():Import #0 module="wasi_snapshot_preview1“错误:模块不是对象或函数
我检查了组件,实际上我的组件需要以下功能:
(func $wasi_snapshot_preview1.fd_close (;0;) (import "wasi_snapshot_preview1" "fd_close") (param i32) (result i32))
(func $wasi_snapshot_preview1.fd_seek (;1;) (import "wasi_snapshot_preview1" "fd_seek") (param i32 i64 i32 i32) (result i32))
(func $wasi_snapshot_preview1.fd_write (;2;) (import "wasi_snapshot_preview1" "fd_write") (param i32 i32 i32 i32) (result i32))
(func $wasi_snapshot_preview1.proc_exit (;3;) (import "wasi_snapshot_preview1" "proc_exit") (param i32))我知道这些函数在纯wasm模块中是不受支持的(比如os调用?)但是我找不到任何关于它们每一个到底是什么的文档。
所以我的问题是:
stb_image头应该只操作没有i/o的内存中的位,为什么需要这些导入的函数?任何标志都会被接受!
编辑
在尝试编译c标准库之后,我了解了这些函数的用途:
fd_write用于打印(通常用于os)fd_seek中的标准输出,而fd_close用于文件manipulation)。
也有
fd_read来读取一个文件,但我不需要在这段代码中
proc_exit以终止进程并可能引发错误。
发布于 2021-06-02 16:23:46
首先,我建议使用-Oz或至少使用-O2构建,这样工具链就可以最大程度地缩小产生的二进制数。
我建议使用-Oz --profiling-funcs进行构建,然后使用wasm-objdump或wasm-decompile来了解这些导入以及最终被使用的原因。
当我这样做的时候,很明显,proc_exit正在被使用,assert_fail。实际上,它们似乎都是由于使用了assert宏,而添加-DNDEBUG使所有这些导入消失。
https://stackoverflow.com/questions/67756028
复制相似问题