javascript 瓦斯结合剂:访问wasm示例的内存缓冲区(从JS)

bmp9r5qi  于 2023-01-16  发布在  Java
关注(0)|答案(2)|浏览(209)

根据这条github注解,我可以通过直接访问wasm示例的内存来重新创建一个Uint 8 ClampedArray或从Rust/wasm返回的Uint 8Array:

const textureRaw = new Uint8ClampedArray(memory.buffer, texture.offset(), texture.size());

问题是,wasm-bindgen生成的js文件已经示例化了一个wasm示例,我想访问这个特定示例的内存,但它似乎没有被导出:

// XXXXX_bg.js

const path = require('path').join(__dirname, 'ed25519_sigs_bg.wasm');
const bytes = require('fs').readFileSync(path);
let imports = {};
imports['./ed25519_sigs.js'] = require('./ed25519_sigs.js');

const wasmModule = new WebAssembly.Module(bytes);
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
module.exports = wasmInstance.exports;

如何访问当前wasm示例的内存缓冲区?

我试过:

import { memory } from "XXXXXX_bg";

// say o is returned as an object with the right offset() and size() accessors. It represents an Uint8Array in memory
let outU8A: Uint8Array = new Uint8Array(
  memory.buffer,
  o.offset(),
  o.size()
);

输出是预期的大小,但每个值都是零。这让我觉得我可能试图从第二个wasm.memory示例加载?

kmbjn2e3

kmbjn2e31#

为了将引用从Rust发送到Javascript,我们使用as_ptr,它是对数据类型开头的引用。它是一个内存地址。

// we are returning a pointer type
// *const is a raw pointer and borrowing rules do not apply
pub fn cells(&self)->*const Cell{
        // as_ptr is the reference to the first item in the vector
        // assume that body:Vec<Cell>
        self.body.as_ptr()
    }

在这个例子中,我发送了一个指向向量类型开头的引用。2你也可以写一个函数来返回向量的长度。

// init().then((wasm) => {} initilaization of js code is like this. 
const cells = new Uint32Array(
   // with memory.buffer you can access to the pointer
   wasm.memory.buffer,
   o.offset(),
   o.size()
);
q5lcpyga

q5lcpyga2#

import { memory } from "XXXXXX_bg";

这个内存导入应该工作正常,但是我猜你试图访问释放的内存。虽然我不知道为什么释放的内存立即显示为零。
我使用静态内存创建了一个简短的工作示例:

#[wasm_bindgen]
pub unsafe fn static_value() -> ByteStream {
    static mut values: [u8; 3] = [0; 3];
    let slice = values.as_mut_slice();
    slice.copy_from_slice(&[1, 2, 3]); // fill with some data
    ByteStream::new(slice)
}

无法访问以下代码的释放内存:

#[wasm_bindgen]
pub fn freed_heap_value() -> ByteStream {
    let mut values = Box::new([0; 3]);
    let slice = values.as_mut_slice();
    slice.copy_from_slice(&[1, 2, 3]); // fill with some data
    ByteStream::new(slice)
}

根据您的用例,您也可以在之后手动释放堆分配:

#[wasm_bindgen]
pub fn heap_value() -> ByteStream {
    let mut values = Box::new([0; 3]);
    let values = Box::leak(values); // has to be freed manually
    let slice = values.as_mut_slice();
    slice.copy_from_slice(&[1, 2, 3]); // fill with some data
    ByteStream::new(slice)
}

相关问题