6

My FFI binding returns a struct with fixed-size c_char arrays, and I would like to turn those into std::ffi::CString or std::String.

It looks like the CString::new function coerces the pointer to a vector.

use std::ffi::CString;
use std::os::raw::c_char;

#[repr(C)]
pub struct FFIStruct {
    pub Id: [::std::os::raw::c_char; 256usize],
    pub Description: [::std::os::raw::c_char; 256usize],
}

fn get_struct() -> Option<FFIStruct> {
    println!("cheating");
    None
}

pub fn main() {
    match get_struct() {
        Some(thing) => 
            println!("Got id:{}",CString::new(thing.Id.as_ptr())),

        None => (),
    }
}

Here is the Rust Playground link.

3 Answers 3

11

C strings that you don't own should be translated using CStr, not CString. You can then convert it into an owned representation (CString) or convert it into a String:

extern crate libc;

use libc::c_char;
use std::ffi::CStr;

pub fn main() {
    let id = [0 as c_char; 256];
    let rust_id = unsafe { CStr::from_ptr(id.as_ptr()) };
    let rust_id = rust_id.to_owned();
    println!("{:?}", rust_id);
}

You should also use the libc crate for types like c_char.

Sign up to request clarification or add additional context in comments.

Comments

2

There is also this kind of solution:

fn zascii(slice: &[c_char]) -> String {
  String::from_iter(slice.iter().take_while(|c| **c != 0).map(|c| *c as u8 as char))
}

Comments

1

you can create std::ffi::CStr from a pointer but you have to use unsafe keyword.Like this

use std::ffi::CStr;
//use std::os::raw::c_char;

#[repr(C)]
pub struct FFIStruct {
    pub id: [::std::os::raw::c_char; 256usize],
    pub description: [::std::os::raw::c_char; 256usize],
}


fn get_struct() -> Option<FFIStruct> {
    println!("cheating");
    None
}
pub fn main() {
    match get_struct() {
        Some(thing) => 
            println!("Got id:{:?}",unsafe{CStr::from_ptr(thing.id.as_ptr())}),

        None => (),
    }
}

you can also convert CStr into String by using this method

CStr::from_ptr(thing.id.as_ptr()).to_string_lossy()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.