gpt4 book ai didi

zlib - 如何将外部 C 库链接到 WebAssembly 构建

转载 作者:行者123 更新时间:2023-12-03 16:35:17 48 4
gpt4 key购买 nike

我正在阅读这篇文章 (https://www.smashingmagazine.com/2019/04/webassembly-speed-web-app/),其中解释了他们如何使用 zlib 来加速他们的 Web 项目:

To support the zlib library, we use the flag USE_ZLIB; zlib is so common that it’s already been ported to WebAssembly, and Emscripten will include it for us in our project



我想在我自己的 WASM 模块中使用 zlib。

在我的 C 代码(用 emcc 编译)中,我编写了这个接口(interface)函数:
#include <zlib.h>

int pcf_decompress_zlib(unsigned char *input, int input_length, unsigned char *output, int output_length)
{
uLongf output_length_result = output_length;
int result = uncompress(output, &output_length_result, input, input_length);
if (result != Z_OK) {
return 0;
} else {
return output_length_result;
}
}

我像这样编译它:
emcc decompress.c -O3 -s WASM=1 -s SIDE_MODULE=1 -s "EXPORTED_FUNCTIONS=['_pcf_decompress_zlib']" -s USE_ZLIB=1 -o decompress.wasm

当我这样做时,emcc 会自动下载到 zlib 库中,所以它似乎知道如何处理这个问题。

然后在浏览器中,我有这个类:
export class Decompressor {
wasmOnLoad(obj) {
this.instance = obj.instance;
console.log("Loaded WASM");
console.log(obj.instance);
// Don't do anything else yet
}

constructor() {
this.memory = new WebAssembly.Memory({
initial: 1
});
this.heap = new Uint8Array(this.memory.buffer);
this.imports = {
env: {
__memory_base: 0,
memory: this.memory,
abort: function(err) {
throw new Error('abort ' + err);
},
}
};
}

start() {
console.log("startWasm");
WebAssembly.instantiateStreaming(fetch('decompress/decompress.wasm'), this.imports)
.then(this.wasmOnLoad.bind(this));
}
}

然后在从我的 HTML 加载的主 JS 代码中:
import { Decompressor } from "./decompress/decompress.js";
var l = new Decompressor();
l.start();

当我加载页面时,Firefox 给我这个错误:
LinkError: import object field '_uncompress' is not a Function

似乎发出的 wasm 代码不包括 zlib,并且 zlib 也没有内置到浏览器中。我想过改变 SIDE_MODULEMAIN_MODULE ,但这会导致数十个 undefined symbol ,使问题变得更糟。

让 emcc 提供 USE_ZLIB=1 是没有意义的。选项如果它没有自动使 zlib 可用。那么我缺少什么来完成这项工作?如何让 emcc 静态包含 的 zlib 代码它已经有 进入我正在编译的 wasm 模块?

谢谢。

最佳答案

一种方法是包含 zlib emcc期间的来源 build 。我在下面测试过。首先,创建这个文件结构(包括你下载的zlib源文件夹)

$ tree -L 2 .
.
├── build.sh
├── dist
├── lib
│   └── zlib-1.2.11
└── src
└── decompress.c

构建.sh
ZLIB="lib/zlib-1.2.11"

emcc \
-O3 \
-s WASM=1 \
-s EXPORTED_FUNCTIONS="[ \
'_free', '_malloc' \
, '_pcf_decompress_zlib' \
]" \
-I $ZLIB \
-o dist/decompress.wasm \
$ZLIB/*.c \
src/decompress.c

现在,配置 zlib 并构建!
$ lib/zlib-1.2.11/configure  `# you only need to run this once`
$ ./build.sh

关于zlib - 如何将外部 C 库链接到 WebAssembly 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61823819/

48 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com