antoyo
antoyo

Reputation: 11913

Missing first character from C string

I am writing a binding to the girara library and I have an issue with the statusbar item text: the first character is missing.

Here is a part of my binding:

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

and here is how I call these functions:

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

But instead of showing girara-left, I only see irara-left.

Is using CString a good way to send *const c_char to a FFI?

Why is the first character missing?

Update

There is something weird hapening here.

If I change the code to:

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

(where text2 is unused), the text hello World is shown, which does not make sense. It seems the pointer does not point at the right place.

Upvotes: 0

Views: 370

Answers (1)

antoyo
antoyo

Reputation: 11913

This issue came by the fact that the CString was dropped before the pointer was sent to the ffi function (see here).

The solution is to bind the CString to a variable:

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

Upvotes: 2

Related Questions