问题
I'm trying to access the different fields of the FILE struct of libc.
FILE implementation in Rust according to the memory mapping in stdio.h:
#[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 FILEs in libc they come in the mut * variant, and this somehow is in the way to access the fields. The following code triggers 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
A variable of type FILE without the mut * variant works but I need to get it working with mut *.
回答1:
FILE is defined as an opaque type, that is:
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.
Anyway, one workaround is to create your own definition of FILE and get a &mut from fp:
#[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.
回答2:
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).
In addition, you'll probably need to wrap the access in an unsafe block, as dereferencing a raw pointer is always an unsafe operation. Try something like this:
let flags = unsafe { (*fp)._flags };
let is_unbuffered = (flags & libc::_IONBF as i16) != 0;
来源:https://stackoverflow.com/questions/38360996/how-do-i-access-fields-of-a-mut-libcfile