如何访问 *mut libc::FILE 的字段?

How do I access fields of a *mut libc::FILE?

我正在尝试访问 libcFILE 结构的不同字段。

FILE 根据 stdio.h:

中的内存映射在 Rust 中实现
#[repr(C)]
pub struct FILE {
    pub _p: libc::c_char,
    pub _r: libc::c_int,
    pub _w: libc::c_int,
    pub _flags: libc::c_short,
    pub _file: libc::c_short,
    ...
}

在 libc 中使用 FILEs 时,它们以 mut * 变体出现,这在某种程度上阻碍了访问字段。以下代码触发 error: attempted access of field_flagson type '*mut FILE', but no field with that name was found

let stdout = libc::fdopen(libc::STDOUT_FILENO, &('w' as libc::c_char));
let is_unbuffered = (fp._flags & libc::_IONBF as i16) != 0

没有 mut * 变体的 FILE 类型的变量可以工作,但我需要让它与 mut * 一起工作。

指针本身没有属性,它指向的结构体有。

所以这意味着您需要访问 *fp._flags,而不是 fp._flags(假设 fp*mut FILE 类型)。

此外,您可能需要将访问包装在 unsafe 块中,因为取消引用原始指针始终是不安全的操作。尝试这样的事情:

let flags = unsafe { (*fp)._flags };
let is_unbuffered = (flags & libc::_IONBF as i16) != 0;

FILE is defined as an opaque type,即:

pub enum FILE {}

所以没有字段可以访问(甚至取消引用原始指针)。


我认为直接访问 FILE 结构的字段不是一个好主意,即使在 C 中也是如此。您应该尝试在 stdio.h 上找到一个函数来执行您想要的操作。


无论如何,一种解决方法是创建您自己的 FILE 定义并从 fp:

中获取 &mut
#[repr(C)]
pub struct MY_FILE {
    pub _p: libc::c_char,
    pub _r: libc::c_int,
    pub _w: libc::c_int,
    pub _flags: libc::c_short,
    pub _file: libc::c_short,
    // ...
}

// ...

unsafe {
    let fp = libc::fdopen(libc::STDOUT_FILENO, &('w' as libc::c_char));
    let fp = &mut *(fp as *mut MY_FILE);
    let is_unbuffered = (fp._flags & libc::_IONBF as i16) != 0;
}

请注意,如果您没有使用 MY_FILE 的正确定义,您将获得一些垃圾数据甚至段错误。