0

我试图Uint8Array在编码后将字符串保存在 Wasm 堆中,并将指向字符串的指针和长度保存在 Struct 中,以便以后可以访问该字符串。下面是我的代码rust

#[wasm_bindgen]
pub struct CustomString{
    ptr : *const u8,
    len: usize
}

#[wasm_bindgen]
impl CustomString{
    pub fn create(len:usize) -> Self{
        let mut d = Vec::with_capacity(len);
        log!("{}",len);

        CustomString{
            ptr: d.as_ptr(),
            len
        }
    }

    pub fn as_ptr(&self) -> *const u8{
        self.ptr
    }

    pub fn print_string(&self){
        let js = unsafe { std::slice::from_raw_parts(self.ptr, self.len) };
        let js = unsafe { std::str::from_utf8_unchecked(js) };
        log!("{}",js) 
    }
}

我的 JS 端代码如下:

function myTest (){
    debugger;
    const { memory } = wasm;
    let encoder = new TextEncoder();
    let mystring = "Ujjal";
    let encodedString = encoder.encode(mystring);

    let length = encodedString.length;
    console.log(length)

    let cs = CustomString.create(length);

    let ptr = cs.as_ptr();

    const asBytes = new Uint8Array(memory.buffer, ptr, length);

    asBytes.set(encodedString);

    return cs;

}

let cs = myTest();


function decode(cs){

    cs.print_string();
}

decode(cs);

理想情况下,它应该打印给定的字符串,但它会显示一些不相关的垃圾值。无法弄清楚出了什么问题,因为我对 rust 和 wasm 还很陌生。

这是我在运行此程序时收到的控制台消息,有时是内存错误。 控制台日志

4

2 回答 2

2

create您创建vec d并获取它的指针时,但在函数结束后被vec d释放并且您的指针指向无效内存。

于 2020-02-22T11:42:06.703 回答
0

所以我终于可以弄清楚了。下面是我的解决方案。

锈代码:

pub struct CustomString{
    ptr : *mut u8,
    len: usize
}

#[wasm_bindgen]
impl CustomString{
    pub fn create(len:usize) -> Self{
        let mut d = String::with_capacity(len);
        // log!("{}",len);
        let ptr = d.as_mut_ptr();
        std::mem::forget(d);
        CustomString{
            ptr,
            len
        }

    }

    pub fn as_ptr(&self) -> *mut u8{
        self.ptr
    }

    pub fn as_string(&self)-> String{
        let m = unsafe { String::from_raw_parts(self.ptr, self.len, self.len) };
        m
    }

    pub fn print_string(&self){
        let m = unsafe { String::from_raw_parts(self.ptr, self.len, self.len) };
        log!("{}",m) 
    }
}

JS代码:

function myCS(string){
    const { memory } = wasm;
    let encoder = new TextEncoder();
    let encodedString = encoder.encode(string);

    let length = encodedString.length;

    let cs = CustomString.create(length);

    let ptr = cs.as_ptr();

    const asBytes = new Uint8Array(memory.buffer, ptr, length);

    asBytes.set(encodedString);

    return cs;

}

这个解决方案的一个问题是它的性能不是很好。我用500000 random length strings. 大约需要4000+ ms.

有没有更好的方法来做到这一点,牢记性能。

于 2020-02-23T11:25:05.283 回答