Эта очень простая программа 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
не связывает стандартную библиотеку (может быть?), Но я не могу найти никого другого с такой же проблемой ...