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

不使用wasm_bindgen时Rust WASM向JS传字符串返回undefined问题

问题分析与解决

核心问题1:WASM不支持直接返回元组

标准WebAssembly目前仅支持返回单个数值类型(i32、i64、f32、f64),你写的Rust函数返回(u8, usize)元组,编译后不符合WASM的函数返回规范,JS无法解析这种非标准返回值,因此得到undefined。

核心问题2:字符串内存被提前释放+指针取错

  • 你用ptr::addr_of!(s)取的是RustString结构体自身的地址,而非字符串底层字节数组的指针。String在Rust里是包含指针、长度、容量的三元结构体,你需要的是它指向的字节数组指针,应该用s.as_ptr()。
  • 函数内的s是局部变量,函数执行完毕后Rust会自动释放它的内存,就算拿到正确指针,后续访问也是野指针,内存已被回收。

修正方案

步骤1:调整Rust代码,解决内存与返回值问题

我们可以把字符串转为静态内存(避免被自动释放),通过两个函数分别返回指针和长度,逻辑更直观:

use std::ffi::CString;

// 全局变量存储字符串指针,供后续获取
static mut GREET_STR: *const u8 = std::ptr::null();

#[no_mangle]
pub fn greet(name: &str) -> usize {
    let s = format!("Hello, {}!", name);
    // 转成CString确保末尾带null终止符(可选,按需使用),通过into_raw让内存脱离Rust的自动释放机制
    let c_str = CString::new(s).unwrap();
    let ptr = c_str.into_raw();
    unsafe {
        GREET_STR = ptr;
    }
    // 返回字符串长度(不含null终止符)
    s.len()
}

#[no_mangle]
pub fn get_greet_ptr() -> usize {
    unsafe { GREET_STR as usize }
}

// 可选:提供内存释放函数,避免内存泄漏
#[no_mangle]
pub fn free_greet_str() {
    unsafe {
        if !GREET_STR.is_null() {
            // 将原始指针转回CString,触发drop释放内存
            let _ = CString::from_raw(GREET_STR as *mut u8);
            GREET_STR = std::ptr::null();
        }
    }
}

步骤2:JS端读取WASM内存

通过wasm.memory获取WASM的内存缓冲区,用Uint8Array读取指定指针和长度的字节,再转为JS字符串:

let wasm = wasmModule.instance.exports;

// 调用greet获取字符串长度,再获取指针
const strLen = wasm.greet("WebAssembly");
const strPtr = wasm.get_greet_ptr();

// 从WASM内存中截取对应字节
const memory = new Uint8Array(wasm.memory.buffer);
const strBytes = memory.subarray(strPtr, strPtr + strLen);

// 解码为JS字符串
const greeting = new TextDecoder().decode(strBytes);
console.log(greeting); // 输出 "Hello, WebAssembly!"

// 使用完毕后手动释放内存,避免泄漏
wasm.free_greet_str();

额外说明

  • 32位/64位WASM下,usize都能被JS正确识别为数值类型。
  • 用CString::into_raw或Box::leak的目的是让内存脱离Rust的自动释放逻辑,必须手动调用释放函数,否则会造成WASM内存泄漏。
  • 也可以把指针和长度打包成一个i64返回(比如指针存低32位、长度存高32位),再在JS端拆分,但双函数的方式更易理解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:20:04