我正在尝试了解 C 代码到 WebAssembly 的转换以及 JavaScript 互操作是如何在后台工作的。我在从函数参数获取简单字符串时遇到问题。
我的程序是一个简单的 Hello World,我正在尝试“模拟”printf
/puts
。
或多或少我想要构建的 C 等价物:
int main() {
puts("Hello World\n");
}
您可以看到一个工作示例 here .
目前我最好的想法是一次读取 16 位内存块(因为 wasm 似乎以 16 位间隔分配它们)并检查空终止符。
function get_string(memory, addr) {
var length = 0;
while (true) {
let buffer = new Uint8Array(memory.buffer, addr, 16);
let term = buffer.indexOf(0);
length += term == -1 ? 16 : term;
if (term != -1) break;
}
const strBuf = new Uint8Array(memory.buffer, addr, length);
return new TextDecoder().decode(strBuf);
}
但这看起来真的很笨拙。如果只知道起始地址,是否有更好的方法从内存中读取字符串?
我真的有必要一次只读取 16 位 block 吗? 如果创建类型化的内存数组算作访问整个内存,或者这仅在我尝试从数组中获取数据时才会发生,我找不到任何信息。
最佳答案
WebAssembly 以 64k 页为单位分配内存。也许这就是 16 位的来源,因为 16 位可以寻址 64 kbytes。然而,这与手头的任务无关,因为 WebAssembly 内存只是一个连续的地址空间,memory
对象和 ArrayBuffer
之间没有太大区别给定尺寸,如果有的话。
一次 16 字节的窗口也不是必需的(16 位以某种方式变成了 16 字节)。
您可以在没有任何性能损失的情况下简单地做到这一点,并通过以下方式创建缓冲区其余部分的 View :
function get_string(memory, addr) {
let buffer = new Uint8Array(memory.buffer, addr, memory.buffer.byteLength - addr);
let term = buffer.indexOf(0);
return new TextDecoder().decode(buffer.subarray(0, term));
}
关于javascript - WebAssembly:从 JavaScript 中的参数(带有内存地址)获取字符串的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51562325/