如何从 WebAssembly 函数返回 JavaScript 字符串?
https://dev.to/azure/passing-strings-from-c-to-javascript-in-web-assembly-1p01 - not working
C
#include <stdio.h>
#include <string.h>
void jsPrintString(const char *s, uint16_t len);
void print() {
const char* str = "Hello from C++!";
jsPrintString(str, strlen(str));
}
编译器:
emcc -Os start.c -s STANDALONE_WASM -s EXPORTED_FUNCTIONS="['_hello']" -s ERROR_ON_UNDEFINED_SYMBOLS=0 -Wl,--no-entry -o "test.wasm"
Javascript:
const memory = new WebAssembly.Memory({ initial: 1 });
function handlePrintString (offset, length) {
console.log(offset, length);
const bytes = new Uint8Array(memory.buffer, offset, length);
const string = new TextDecoder('utf8').decode(bytes);
console.log(string); //empty ???????????????????????????????????
}
const importObject = {
env: {
jsPrintString: handlePrintString,
memory: memory
},
js: { mem: memory }
};
WebAssembly.instantiateStreaming(fetch('/js/test.wasm'), importObject)
.then(obj => {
console.log(obj.instance.exports);
console.log(obj.instance.exports.print());
});
memory ArrayBuffer [
0,0,0,0,0,0,0,0,0,0,0,0....] ???如何从 WebAssembly 函数返回 JavaScript 字符串?
你不能。 你必须把它复制到与JavaScript共享的内存中。
void hello(char *array) {
const my_string = "Hello from C++!";
memcpy(array, my_string, strlen(my_string));
}
(async () => {
const response = await fetch('/js/test.wasm');
const bytes = await response.arrayBuffer();
const results = await WebAssembly.instantiate(bytes, {});
const { instance: { exports: { memory, hello } }} = results;
const array = new Uint8Array(memory.buffer, 0, 15);
hello(array.byteOffset);
console.log(new TextDecoder('utf8').decode(array)); // Hello from C++!
})();
你的代码快到了,可以按照你的暗示去做。您不必像顶部注释所述显式复制到共享内存。这篇博文对此进行了更详细的解释 此处.
C 代码:
const char* getString() {
return "Hello World!";
}
编译它
clang --target=wasm32 -nostdlib -Wl,--no-entry -Wl,--export-all -o main.wasm main.c
和JS代码:
var importObject = { imports: { imported_func: arg => console.log(arg) } };
WebAssembly.instantiateStreaming(fetch('main.wasm'), importObject)
.then(obj => {
var charArray = new Int8Array(
obj.instance.exports.memory.buffer, // WASM's memory
obj.instance.exports.getString(), // char's pointer
12 // The string's length
);
// Convert from ASCII code to char
let string = String.fromCharCode.apply(null, charArray)
console.log(string);
});