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

Convert from a fixed-sized c_char array to CString

我的 FFI 绑定 returns 一个具有固定大小 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 link.

您不拥有的 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);
}

您还应该为 c_char.

等类型使用 libc crate

您可以从指针创建 std::ffi::CStr 但您必须使用不安全的 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 => (),
    }
}

你也可以用这个方法将CStr转成String

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

还有这种解决方法:

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