Я следую решениям отсюда: Как я могу вернуть строку JavaScript из функции WebAssembly и здесь: Как вернуть строку (или аналогичную) из Rust в 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 и добавлю 8 к смещению (которое было 32), чтобы смещение составило 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 байтов к смещению?
Итак, что здесь происходит?
Редактировать: Еще одна подсказка, если я использую TextDecoder в массиве UInt8, декодирование как UTF-16 выглядит более правильным, чем декодирование как UTF-8: