c - Read raw C string to Rust...在此上下文中将有符号转换为无符号的正确方法是什么?

标签 c string vector utf-8 rust

我正在将一些 C 函数绑定(bind)到 rust。我遇到了一个小问题,我想知道用 Rust 解决它的正确方法。

这是我想从 C API 调用的函数:

extern "C" {
    pub fn H5Aread(attr_id: hid_t, type_id: hid_t, buf: *mut c_char) -> herr_t;
}

该函数从文件中读取内容,并将其存储在 buf 中.

所以,我在 vector 中创建了这个缓冲区:

let len: u64 = get_the_length();

let attr_raw_string: Vec<c_char> = Vec::new(); // c_char is equivalent to i8
attr_raw_string.resize(len as usize, 0);
let attr_raw_string_ptr = attr_raw_string.as_mut_ptr();

let read_error = H5Aread(attr_obj, attr_type, attr_raw_string_ptr);
if read_error < 0 {
    panic!("...");
}
let result_str: String = String::from_utf8(attr_raw_string);

现在不能编译因为from_utf8期望一个 Vec<u8> ,但是Vec<c_char>Vec<i8> .

有没有办法解决这个问题,而不必每次都将字符串复制并转换为新类型 u8

最佳答案

你快到了。

现在,我们假设您的 FFI 边界的 C 端是正确的 - 即它正确地生成了一个以 null 结尾的字符串。

为了在 Rust 中有效地分配和恢复它,我们将使用 CStr .这会创建一个引用内存中 C 字符串的借用类型(即 *const char )。这不会分配,因为它不是一个拥有的类型。

然后我们将其转换为 &str与我们的预期进行最终比较。这仍然不是一个拥有的类型,所以我们创建的只是我们的 Vec<>我们有效地用作缓冲区。

完整代码可在下方和 playground 上找到:

#[test]
fn test() {
    let len:u64 = 64;
    // Allocate a buffer
    let mut buffer:Vec<c_char> = Vec::with_capacity(len as usize);
    let attr_raw_string_ptr = buffer.as_mut_ptr();

    let read_error = unsafe { H5Aread(attr_raw_string_ptr) };
    if read_error < 0 {
        panic!("...");
    }
    let result = unsafe {
        CStr::from_ptr(attr_raw_string_ptr)
    };
    let result_str = result.to_str().unwrap();
    assert_eq!(result_str, "test");
}

三个重要的陷阱:

  1. CStr::to_str()可能会失败(因此当 Result<&str, _> 的内容不是有效的 utf-8 时它返回 CStr 的原因。这是因为 rust String&str 类型都需要是有效的 utf-8。<
  2. 显然,您的输入缓冲区需要至少有您的 C 函数将投入其中的大小。向C方提出保证即可。
  3. CStr::from_ptr有一个bunch of gotchas在使用它时你至少应该牢记这一点

关于c - Read raw C string to Rust...在此上下文中将有符号转换为无符号的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58146208/

相关文章:

c++ - 如何在 matlab 中使用 kd-tree 文件交换和 mex?

c - malloc困惑

c - 共享名为 POSIX 信号量

c# - 在小写和大写之间添加间距?

c - 如何在 C 中将 4 个数字打印为字符串?

c++ - 从尝试引用已删除函数的 vector C++ 中删除对象

c - 将控制字符放在字符串中是否安全?

javascript - javascript 字符串比较

c++ - 为什么使用指针 vector 被认为是不好的?

c++ - 当我返回指向结构的指针 vector 时出现段错误