You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否无拷贝将WebAssembly::Memory转为Rust切片?跨DLL/WASM实现

WebAssembly Memory 转 Rust 原生切片的实现方案

要完成&WebAssembly::Memory到&mut [u8]/&[u8]的转换,核心是获取共享内存的起始指针和总字节长度,再通过unsafe操作构造Rust切片。以下是具体实现:

依赖配置

首先在Cargo.toml中添加必要依赖:

[dependencies]
wasm-bindgen = "0.2"
js-sys = "0.3"

完整代码实现

use wasm_bindgen::prelude::*;

// 定义与JS WebAssembly.Memory对应的绑定类型
#[wasm_bindgen]
extern "C" {
    #[derive(Clone, Debug)]
    type Memory;

    #[wasm_bindgen(method, getter)]
    fn buffer(this: &Memory) -> JsValue;
}

#[wasm_bindgen]
pub fn write_to_shared_memory(mem: &Memory) {
    // 将Memory的buffer转为Uint8Array,方便获取指针和长度
    let uint8_arr = js_sys::Uint8Array::new(&mem.buffer());
    
    // 获取内存起始指针和总字节数
    let ptr = uint8_arr.as_mut_ptr();
    let len = uint8_arr.length() as usize;

    // 构造可变切片(unsafe操作,无有效性校验)
    let mem_slice = unsafe { std::slice::from_raw_parts_mut(ptr, len) };
    write_impl(mem_slice);
}

// 核心逻辑:纯Rust实现,可直接用于DLL编译
pub fn write_impl(mem: &mut [u8]) {
    for i in 0..100 {
        mem[i] = i as u8;
    }
}

#[wasm_bindgen]
pub fn read_from_shared_memory(mem: &Memory) -> JsValue {
    let uint8_arr = js_sys::Uint8Array::new(&mem.buffer());
    
    let ptr = uint8_arr.as_ptr();
    let len = uint8_arr.length() as usize;

    // 构造不可变切片
    let mem_slice = unsafe { std::slice::from_raw_parts(ptr, len) };
    read_impl(mem_slice).into()
}

// 核心逻辑:纯Rust实现
pub fn read_impl(arr: &[u8]) -> u8 {
    arr[0]
}

关键步骤解析

  1. Memory绑定与buffer获取:通过wasm_bindgen的extern块定义Memory类型,并绑定其buffer getter方法,拿到JS侧的ArrayBuffer。
  2. Uint8Array包装:用js_sys::Uint8Array包装ArrayBuffer,它提供了直接获取内存指针和长度的API,比手动transmute更直观。
  3. 切片构造:
    • 可变切片用std::slice::from_raw_parts_mut,不可变用std::slice::from_raw_parts,这两个都是unsafe操作,因为Rust无法保证内存的合法性、生命周期和线程安全。

额外说明

  • 无需使用std::mem::transmute,Uint8Array的指针API已经足够完成转换,且可读性更强。
  • 核心的write_impl和read_impl完全基于原生Rust类型,剥离#[wasm_bindgen]相关代码后,可直接编译为DLL(需添加DLL导出属性,如#[no_mangle]等)。
  • 如你所述,该操作存在极高风险:无边界检查、共享内存数据竞争、JS侧内存修改会导致Rust侧未定义行为,仅适合学习研究使用。

内容的提问来源于stack exchange,提问作者stevendesu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:19:52