从固定大小的c_char数组转换为CString

时间:2016-05-24 18:37:11

标签: rust ffi

我的FFI绑定返回一个包含固定大小c_char数组的结构,我想将它们转换为std::ffi::CStringstd::String

看起来CString::new函数强制指向向量的指针。

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 => (),
    }
}

以下是Rust Playground链接。

2 个答案:

答案 0 :(得分:6)

您不拥有的C字符串应使用CStr进行翻译,而不是CString。然后,您可以将其转换为自有代表(CString)或将其转换为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);
}

您还应该使用libc crate来处理c_char等类型。

答案 1 :(得分:1)

你可以从指针创建std :: ffi :: CStr,但你必须使用unsafe关键字。就像这个

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 => (),
    }
}

您也可以使用此方法将CStr转换为String

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