2016-05-14 8 views
0

giraraライブラリへのバインディングを作成していますが、ステータスバーの項目テキストに問題があります。最初の文字がありません。C文字列の先頭文字がありません

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を参照してください。

#[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); 
} 

、ここでは、私はこれらの関数を呼び出す方法です。ここで

は私の結合の一部です。

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関数(here参照)に送信される前に、CStringが削除されたことによって発生しました。

ソリューションは、変数へ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

関連する問題