WebAssembly LinkError, когда включена стандартная библиотека - PullRequest
0 голосов
/ 14 марта 2019

Эта очень простая программа WebAssembly прекрасно работает для меня:

test.c

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

test.html

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

Я использую:

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

Но тогда, если я попробую что-то вроде:

test.c

#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, но это немного изменило сообщение об ошибке:

LinkError: import object field '___setErrNo' is not a Function

Я не очень много знаю о WebAssembly, поэтому я не уверен, что здесь происходит. Что именно вызывает эту ошибку?

Edit:

Интересно, что я вообще не получаю никакой ошибки, если позвоню 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

Из сообщения об ошибке кажется, что emcc не связывает стандартную библиотеку (может быть?), Но я не могу найти никого другого с такой же проблемой ...

1 Ответ

0 голосов
/ 15 марта 2019

Я наконец заставил его работать, получив 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

Я до сих пор не совсем уверен, что было не так раньше ... но, по крайней мере, сейчас это работает.

...