包含标准库时的WebAssembly LinkError

时间:2019-03-14 19:34:47

标签: javascript c webassembly

这个非常简单的WebAssembly程序对我来说很好用:

test.c

01 1F 00

test.html

int testing(void) {
    return 10;
}
int main(void) {
    return 0;
}

我正在使用:

<html>
    <body>
        <script>
            var imports = {};

            function instantiate(bytes, imports) {
                return WebAssembly.compile(bytes).then(m => new WebAssembly.Instance(m, imports));
            }
            fetch('test.wasm').then(response => response.arrayBuffer())
                .then(bytes => instantiate(bytes, imports))
                .then(instance => { 
                    console.log(instance.exports._testing());
                } );

        </script>
    </body>
</html>

但是,如果我尝试以下操作:

test.c

emcc test.c something.c -s "EXPORTED_FUNCTIONS=['_testing']" -s WASM=1 -O3 -o test.wasm

首先,它会产生此错误:

#include <stdio.h>
int testing(void) {
    printf("Hello!\n");
    return 10;
}
int main(void) {
    return 0;
}

我尝试通过向TypeError: import object field 'env' is not an Object 添加env字段来解决这个问题:

imports

但这给了我另一个错误:

var imports = {
    env: {
        memoryBase: 0,
        tableBase: 0,
        memory: new WebAssembly.Memory({
            initial: 512
        }),
        table: new WebAssembly.Table({
            initial: 0,
            element: 'anyfunc'
        })
    }
};

我也尝试使用LinkError: import object field '___syscall146' is not a Function ,但这只是稍微改变了错误消息:

-s EXPORT_ALL=1

我对WebAssembly的了解并不多,所以我不确定这里发生了什么。究竟是什么导致此错误?

编辑:

有趣的是,如果我打LinkError: import object field '___setErrNo' is not a Function ,我什么都不会出错:

malloc

但是,如果我从任何已分配的内存中返回值:

#include <stdlib.h>
int testing(void) {
    int* p = malloc(5);
    *p = 17;
    free(p);
    return 7;
}
int main(void) {
    return 0;
}

我再次得到这个:

#include <stdlib.h>
int testing(void) {
    int* p = malloc(5);
    *p = 17;
    free(p);
    return *p;
}
int main(void) {
    return 0;
}

从错误消息中,看来LinkError: import object field '___setErrNo' is not a Function 没有链接标准库(也许?),但是我找不到其他人遇到相同的问题...

1 个答案:

答案 0 :(得分:0)

我终于通过让emcc直接输出.js文件来使其工作:

test.c

#include <stdio.h>

void testing(void) {
    printf("Hello!\n");
}

int main(void) {
    return 0;
}

test.html

<html>
  <body>
    <script src="test.js"></script>
    <script>
        Module.onRuntimeInitialized = function() {
            _testing();
        }
    </script>

  </body>
</html>
emcc test.c -s EXPORTED_FUNCTIONS=['_testing'] -s WASM=1 -O3 -o test.js

我仍然不完全确定以前哪里出了问题...但是至少现在可以正常工作了。