2016-05-14 49 views
0

我正在寫一個對girara庫的綁定,並且狀態欄項目文本有問題:第一個字符丟失。缺少C字符串的第一個字符

這裏是我的綁定的一部分:

#[link(name="girara-gtk3")] 
extern "C" { 
    // Statusbar. 
    pub fn girara_statusbar_item_add(session: *mut girara_session_t, 
            expand: bool, 
            fill: bool, 
            left: bool, 
            callback: girara_statusbar_event_t) 
            -> *mut girara_statusbar_item_t; 
    pub fn girara_statusbar_item_set_text(session: *mut girara_session_t, 
              item: *mut girara_statusbar_item_t, 
              text: *const c_char); 
} 

,這裏是我如何調用這些函數:

let item = unsafe { girara_statusbar_item_add(session, true, true, true, None) }; 
assert!(item != 0 as *mut _); 

let text = CString::new("girara-left").unwrap().as_ptr(); 
unsafe { girara_statusbar_item_set_text(session, item, text) }; 

而不是顯示girara-left但是,我只看到irara-left

正在使用CString*const c_char發送到FFI的好方法?

爲什麼第一個字符丟失?

更新

這裏有一些奇怪hapening。

如果我的代碼更改爲:

let text = CString::new("girara-left").unwrap().as_ptr(); 
let text2 = CString::new("hello World").unwrap(); 
unsafe { girara_statusbar_item_set_text(session, item, text) }; 

(其中text2未使用),文本hello World所示,這是沒有意義的。看起來指針並不指向正確的位置。

回答

2

這個問題是因爲在指針被髮送到ffi函數之前丟棄了CString(參見here)。

的解決方案是將CString綁定到一個變量:

let text = CString::new("girara-left").unwrap(); 
unsafe { girara_statusbar_item_set_text(session, item, text.as_ptr()) }; 
+1

,並確保你的''girara_statusbar_item_set_text功能不保留超出'CString'多久住該字符串的參考... ! – Shepmaster

+2

請注意,Clippy具有[皮毛](https://github.com/Manishearth/rust-clippy/wiki#temporary_cstring_as_ptr)(聲明:我是Clippy的貢獻者)。 – mcarton

相關問題