简体   繁体   English

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

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

I'm trying to access the different fields of the FILE struct of libc . 我正在尝试访问libcFILE结构的不同字段。

FILE implementation in Rust according to the memory mapping in stdio.h : 根据stdio.h的内存映射,Rust中的FILE实现:

#[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,
    ...
}

when working with FILE s in libc they come in the mut * variant, and this somehow is in the way to access the fields. 在libc中使用FILE ,它们使用mut *变体,这以某种方式妨碍了访问字段。 The following code triggers error: attempted access of field _flags on type '*mut FILE', but no field with that name was found . 以下代码触发error: attempted access of field on type '*mut FILE', but no field with that name was found error: attempted access of field _flags on 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

A variable of type FILE without the mut * variant works but I need to get it working with mut * . 没有mut *变体的FILE类型的变量可以工作,但是我需要让它与mut *一起工作。

FILE is defined as an opaque type , that is: FILE被定义为不透明类型 ,即:

pub enum FILE {}

So there is no field to access (even dereferencing the raw pointer). 因此,没有字段可访问(甚至取消引用原始指针)。


I think it is not a good idea to access the fields of FILE structure directly, even in C. You should try to find a function on stdio.h that do what you want. 我认为,即使在C语言中,直接访问FILE结构的字段也不是一个好主意。您应该尝试在stdio.h上找到一个可以执行所需功能的函数。


Anyway, one workaround is to create your own definition of FILE and get a &mut from fp : 无论如何,一种解决方法是创建自己的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;
}

Note that if you do not use the correct definition for MY_FILE , you will get some garbage data or even a segfault. 请注意,如果未对MY_FILE使用正确的定义,则会得到一些垃圾数据甚至是段错误。

The pointer itself doesn't have attributes, the struct it points to does. 指针本身没有属性,指针所指向的结构却具有属性。

So what this means is that you need to access *fp._flags , not fp._flags (assuming fp is of type *mut FILE ). 因此,这意味着您需要访问*fp._flags ,而不是fp._flags (假设fp*mut FILE类型)。

In addition, you'll probably need to wrap the access in an unsafe block, as dereferencing a raw pointer is always an unsafe operation. 另外,您可能需要将访问包装在unsafe块中,因为取消引用原始指针始终是不安全的操作。 Try something like this: 尝试这样的事情:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM