首页 > 解决方案 > 如何将原始元素类型的数组从 JavaScript 快速传递到 Rust 中的 wasm?

问题描述

让我问一下如何将包含 uint8 元素的数组从 javascript 快速传递到 Rust 中的 wasm?

我在以下位置找到了一种方法:As JsValue

虽然我想知道当所有元素值都是相同的原始类型并且在特定范围内时是否有一些明显更快的。

例如,您将 uint8 数组编码为字符串,然后将字符串传递给 wasm,而不是通过 JsValue。

或者我想知道您是否可以不通过 JsValues 将任何原始元素类型的数组传递给 wasm。

编辑:阅读第一个答案后,我尝试按照以下理解来遵循答案。这似乎是成功的。我的理解正确吗?


import * as wasm from "../pkg";
import * as bg_wasm from '../pkg/PACKAGE_NAME_bg.wasm';
const RUST_STRUCT = wasm.RUST_STRUCT.new();

const cellsPtr = RUST_STRUCT.cells();
const cells = new Uint8Array(bg_wasm.memory.buffer, cellsPtr, 100);
console.log( cells[50]);// 0
for(let i=0;i<100;i++){cells[i]=i;}
console.log( cells[50]);//50
console.log( "end");

vec::泄漏

标签: javascriptrustwebassemblywasm-bindgen

解决方案


WASM 虚拟机有自己的内存地址空间,从 JS 来看就是一个大的ArrayBuffer通常命名为wasm.memory. 您从 JS 传递到 WASM 的任何值都必须从其自己的变量复制到该内存。

但是有一个很好的技巧。如果你从 Rust 端分配一个缓冲区,比如 a Vec<u8>,然后以某种方式将它的引用传递给 JS,那么&mut [u8]它将变成 JS Uint8Array,这实际上是 Rust 内存的直接视图。零复制开销。

您只需要注意不要以破坏任何 Rust 不变量的方式使用来自 JS 的引用,例如将其作为另一个引用传回,这样您就可以得到两个&mut _相同的值。此外,只要 JS 持有引用,你就必须在 Rust 中保持这个内存活着。Vec::leak()调用缓冲区以使其内存永远存在甚至可能是一个好主意。


推荐阅读