在 WebAssembly 和 JavaScript 之间传输字节数组 (Uint8Array)

Posted

技术标签:

【中文标题】在 WebAssembly 和 JavaScript 之间传输字节数组 (Uint8Array)【英文标题】:Transfer byte array (Uint8Array) between WebAssembly and JavaScript 【发布时间】:2020-05-05 02:15:08 【问题描述】:

我在 WebAssembly 代码中有一个 u8[] 数组,如何在常规 JS 中读取它?调用它只会给我一个 i32。

// Load module WebAssembly.Instance
const instance = await getInstance("./build/embed.wasm");

// Try to get the array of bytes from the module
const embeddedFileBytes = Uint8Array.from(instance.fileBytes);

// write the file to disc
await writeFile("./output.text", embeddedFileBytes);

// check the hash is the same as the original file that was embedded
expect(sha1("./output.text")).toEqual(sha1("./input.text"))

webassembly 模块有一个导出:

export const fileBytes: u8[] = [83,65,77,80,76,69,10];

【问题讨论】:

您能提供您工作的任何示例代码吗?否则我不能举个例子。 添加示例代码感谢@BumsikKim 谢谢,但是那个 WebAssembly 模块是用什么写的?它只是一个单行吗?还有getInstance()是什么?它不是标准的 WebAssembly API,那么您为 JS 代码使用了什么样的库?由于您已经没有使用“常规 JS”,请提供更具体的上下文... 请注意,这不仅仅是关于 WebAssembly 的问题,而是关于 WebAssembly 框架的问题。所以你可能想在你的问题中添加额外的标签。 【参考方案1】:

WebAssembly 是只支持数字类型的低级虚拟机。更复杂的类型,例如字符串、结构和数组,在 WebAssembly 的 linear memory 中进行编码 - 这是 WebAssembly 和 javascript 都可以读取和写入的连续内存块。

fileBytes 返回的值不是数组本身,而是指向线性内存中数组位置的指针。为了从数组中获取数据,您需要从线性内存中读取它 - 与读取字符串的方式大致相同,如下面的问题所述:

How can I return a JavaScript string from a WebAssembly function

如果您不想自己编写此“胶水”代码,我建议您查看wasm-bindgen

【讨论】:

谢谢,一分钱掉了,我现在明白了。我检查了 WebAssembly/binaryen 中可用的“胶水”,并找到了一种方法 (__getUint8Array) 使用它们的加载器来提取字节

以上是关于在 WebAssembly 和 JavaScript 之间传输字节数组 (Uint8Array)的主要内容,如果未能解决你的问题,请参考以下文章

嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素

asm.js 和 WebAssembly 有啥区别?

通过漫画介绍WebAssembly

WebAssembly简单指导---译

图书WebAssembly实战

在 Rust 程序和嵌入式 WebAssembly 运行时之间进行通信的最佳实践是啥?