How to wrap `printf` in libc properly?

I try to wrap printf just like the following code:

extern crate libc;
use libc::{c_char, c_int};

extern "C" {
    fn printf(fmt: *const c_char, ...) -> c_int;
}
fn main() {
    unsafe {
        printf("hello world\n".as_ptr() as *const i8);
    }
}

But it prints something really strange...


However, if I append extra \0 to string I want to print, it prints properly.

extern crate libc;
use libc::{c_char, c_int};

extern "C" {
    fn printf(fmt: *const c_char, ...) -> c_int;
}
fn main() {
    unsafe {
        printf("hello world\n\0".as_ptr() as *const i8);
    }
}

Is it a bug or I didn't wrap the C function properly?

C strings are zero-terminated. Rust strings are not. This is why the CStr and CString types exist.

5 Likes

Thanks! :star_struck:

Warning in advance - assing CString to a variable before calling as_ptr() on it. Temporary value (not assigned to a variable) will give invalid, crash-inducing pointer.

assing CString

  • kornel, 2018
2 Likes

I always like linking to your original post on the CString::as_ptr() issue.