缺少C字符串中的第一个字符

时间:2016-05-14 20:10:30

标签: rust ffi

我正在写girara库的绑定,我对状态栏项目文本有疑问:第一个字符缺失。

以下是我绑定的一部分:

#[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的好方法吗?

为什么缺少第一个角色?

更新

这里有一些奇怪的事情。

如果我将代码更改为:

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,这没有意义。似乎指针没有指向正确的位置。

1 个答案:

答案 0 :(得分:2)

这个问题来自于CString在指针发送到ffi函数之前被删除的事实(参见here)。

解决方案是将CString绑定到变量:

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