内存 – 从Rust编译到Emscripten的Javascript中获取数组

我想生成一个字节向量(Rust中的Vec< u8>)并使用JS作为Array或Uint8Array访问它,并将其发送到WebSocket或IndexedDB.

我找到了How can I pass an array from JavaScript to Rust that has been compiled with Emscripten?,这与我想做的完全相反,但非常相关.除此之外,我知道Emscripten中的数组类型,但我不知道如何正确使用它.

我对如何使其工作的最佳猜测是尝试返回向量as_mut_ptr,并使用Module.HEAPU8上的指针.

main.rs

#[no_mangle]
pub fn bytes() -> *mut u8 {
    vec![1, 2, 3].as_mut_ptr()
}

fn main() {}

index.html的一部分

var Module = {
    wasmBinaryFile: "site.wasm",
    onRuntimeInitialized: main,
};
function main() {
    let ptr = Module._bytes();
    console.log(ptr);
    console.log(Module.HEAPU8.slice(ptr, ptr + 10));
    console.log(Module.HEAPU8.subarray(ptr, ptr + 100));
    let arr = Module.cwrap('bytes', 'array', []);
    console.log(arr());
}

控制台的结果最终看起来像这样:

5260296  site:11:13
Uint8Array [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]  site:12:13
Uint8Array [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90 more… ]  site:13:13
5260296  site:15:13

第一个问题是两个值都表示空数组,其次两个单独的调用指向相同的内存位置.我完全不知道如何访问堆上指向的数据,以及向量的长度.

指向相同存储器位置的两个指针可能是因为Rust掉落了Vec< u8>.在它的生命周期结束时写入(字节结束)函数.

对不起,如果我错过了一些Wasm和Emscripten的基础知识,我今天只建立了我的第一个Wasm hello world.

最佳答案 与编写Rust相同的规则适用于此处.这意味着该函数必须返回一个拥有的值;当前它返回一个指向函数返回时丢弃的数据的指针.

一个人将返回Vec< u8>它包括(ptr,长度,容量)并且太大而无法返回C.

有两种类似的解决方案:

> return Box< Vec< u8>>并定义另一个提取的函数
它的指针.
>定义您可以从C访问的自己的Vec.

我使用后者here.

点赞