字符串变换的 Rust、FFI 和生命周期

Rust, FFI, and lifetime for string transmutation

我在 FFI 库中工作,遇到这种模式很多次,我不知道如何以惯用的方式处理。

impl CanVoidStar for str {
    fn as_cvoid_ptr(&self) -> *const c_void {
        let string = CString::new(self).unwrap(); 
        unsafe {
            return mem::transmute(string.as_ptr());
        }
    }
}

我的意图是创建一个 const *void 指向一块内存的指针,我可以将其交给 C 函数。这里的问题是 string 超出范围,因此我在 unsafe 块中得到未定义的行为。

有没有一种方法可以让 string 在堆上分配,直到使用 return 值的任何东西都用完了?此外,是否有一种惯用的方法来处理这个问题,或者我是否需要重新设计我的算法?

看来您在 CString 上使用了错误的方法,而 CString::into_raw() 正是您想要的。更好的是,它不需要 unsafe 代码,直到您想再次释放内存。

CString::as_ptr() returns 将指针指向字符串,CString::into_raw() 将内存的所有权传递给原始指针;这正是针对您的用例:

trait CanVoidStar {
    fn as_cvoid_ptr(&self) -> *const c_void;
}

impl CanVoidStar for str {
   fn as_cvoid_ptr(&self) -> *const c_void {
        let string = CString::new(self).unwrap();
        string.into_raw() as *const c_void
    }
}

如文档所述,如果您想释放它,则需要使用 CString::from_raw() 重建 CString,然后像往常一样删除它。