2016-09-02 54 views
0

我正在FFI庫中工作,並且遇到過這種模式,我不知道如何處理地道。鐵鏽,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,直到它使用返回值完成它爲止?此外,有沒有一種慣用的方式來處理這個問題,還是我需要重新設計我的算法?

+0

http://jakegoulding.com/rust-ffi-omnibus/ – Shepmaster

回答

4

看起來你在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,然後把它降到如常。

+0

這是_exactly_我​​需要和按預期工作。謝謝克里斯。 – sholsapp