如何将外部 C 库链接到 WebAssembly Build



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

为了支持 zlib 库,我们使用标志USE_ZLIB;zlib 非常普遍,它已经被移植到 WebAssembly 中,Emscripten 将它包含在我们的项目中

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

在我的 C 代码(使用 emcc 编译(中,我编写了以下接口函数:

#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_MODULE更改为MAIN_MODULE,但这导致了数十个未定义的符号,使问题变得更糟。

如果 emcc 没有自动使 zlib 可用,那么让 EMC 提供一个USE_ZLIB=1选项是没有意义的。那么我错过了什么才能完成这项工作?如何让 emcc 静态地将它已经拥有的 zlib 代码包含在我正在编译的 wasm 模块中?

谢谢。

一种方法是在emcc构建期间包含 zlib 源代码。我在下面测试过。 首先,创建此文件结构(包括您下载的 zlib 源文件夹(

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

build.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

相关内容

  • 没有找到相关文章

最新更新