我正在从这里关注解决方案: How can I return a JavaScript string from a WebAssembly function 和这里: How to return a string (or similar) from Rust in WebAssembly?
但是,当从内存中读取时,我没有得到想要的结果。
AssemblyScript文件helloWorldModule.ts:
export function getMessageLocation(): string {
return "Hello World";
}
index.html:
<script>
fetch("helloWorldModule.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, {imports: {}})
).then(results => {
var linearMemory = results.instance.exports.memory;
var offset = results.instance.exports.getMessageLocation();
var stringBuffer = new Uint8Array(linearMemory.buffer, offset, 11);
let str = '';
for (let i=0; i<stringBuffer.length; i++) {
str += String.fromCharCode(stringBuffer[i]);
}
debugger;
});
</script>
这将返回32的偏移量。最后产生一个字符串,该字符串以太早开始,并且在“ Hello World”的每个字母之间都有空格:
但是,如果我将数组更改为Int16Array,并向偏移量(即32)加上8,则将偏移量设置为40。
<script>
fetch("helloWorldModule.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, {imports: {}})
).then(results => {
var linearMemory = results.instance.exports.memory;
var offset = results.instance.exports.getMessageLocation();
var stringBuffer = new Int16Array(linearMemory.buffer, offset+8, 11);
let str = '';
for (let i=0; i<stringBuffer.length; i++) {
str += String.fromCharCode(stringBuffer[i]);
}
debugger;
});
</script>
为什么第一组代码不能像我提供的链接中那样工作?为什么我需要更改它才能与Int16Array配合使用,以摆脱例如“ H”和“ e”之间的空间?为什么我需要在偏移量上增加8个字节?
总而言之,这到底是怎么回事?
编辑:另一个线索是,如果我在UInt8数组上使用TextDecoder,则解码为UTF-16看起来比解码为UTF-8更正确:
答案 0 :(得分:1)
AssemblyScript使用utf-16:https://github.com/AssemblyScript/assemblyscript/issues/43
另外,AssemblyScript将字符串的长度存储在前32位或64位中。
这就是为什么我的代码表现不同的原因。这篇文章顶部链接中的示例适用于C ++和Rust,它们对字符串的编码方式有所不同