C 字符串 FFI:是否有类似 String::from_raw_buf_with_max_len 的东西

C string FFI: Is there something like String::from_raw_buf_with_max_len

注意(2015 年 5 月):这个问题是关于 Rust 语言在稳定和 1.0 发布之前的,现在主要是历史意义:代码不会编译稳定的 Rust 等


我正在为我正在从事的项目编写 libpcap 的包装器,并学习 Rust(我刚刚开始这样做)。我现在正在围绕这个写一个安全的 Rust:

#[link(name = "pcap")]
extern {
    fn pcap_lookupdev(errormsg: *mut libc::c_char) -> *const libc::c_char;
}

这是我目前得到的:

fn lookupdev() -> Result<String, String> {
    // Capacity must be at least PCAP_ERRBUF_SIZE
    let mut errbuf = [0 as c_char, ..256];

    let result = unsafe {
        let ptr = pcap_lookupdev(errbuf.as_mut_ptr() as *mut libc::c_char);
        if ptr.is_null() {
            None
        }
        else {
            Some(CString::new(ptr, false))
        }
    };

    match result {
          Some(result) => Ok(result.as_str().unwrap().to_string()),
          None => Err(unsafe { String::from_raw_buf(errbuf.as_ptr() as *const u8) })
    }
}

这行得通,但我不喜欢 String::from_raw_buf 的用法,它会愉快地遍历千兆字节的内存,而不是在到达 errbuf 末尾时停止。

我可以写一些东西来手动循环 errbuf 并将其转换为 Rust 字符串(在缓冲区末尾停止),但在我看来这是字符串的 C FFI 习惯用法(传递一个Rust 标准库应该支持的分配的内存块,可以在其中写入字符串)。但是,我在 Rust FFI 指南和标准库文档中找不到任何内容。

在 Rust 中处理这个 FFI 案例的最佳方法是什么?是否至少有 String::from_raw_buf_with_maxlenString::from_array

Rust 标准库本身似乎并没有真正处理这种可能性:

这可能是无意的,IMO,应该用 Rust 提交错误。

所以我认为目前没有简单的解决方案。我能想到的是这个

#![feature(slicing_syntax)]

extern crate libc;

use std::c_str::CString;

fn main() {
    let errbuf = ['o' as libc::c_char; 256];
    if errbuf.iter().any(|c| *c == 0 as libc::c_char) {
        unsafe { CString::new(errbuf.as_ptr(), false).to_string() };
    } else {
        panic!("FFI returned invalid string!");
    }
}