【问题标题】:Rust, FFI, and lifetime for string transmutation字符串转换的 Rust、FFI 和生命周期
【发布时间】:2016-09-02 02:28:31
【问题描述】:

我在一个 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 一直分配在堆上,直到它使用返回值为止?此外,有没有一种惯用的方法来处理这个问题,还是我需要重新设计我的算法?

【问题讨论】:

标签: rust ffi lifetime


【解决方案1】:

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

CString::as_ptr() 返回指向字符串的指针,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,然后像往常一样将其删除。

【讨论】:

  • 正是我需要的并且按预期工作。谢谢克里斯。
猜你喜欢
  • 2020-04-20
  • 1970-01-01
  • 2013-07-03
  • 2014-07-31
  • 2014-12-29
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
相关资源
最近更新 更多