Dank @Matthieu M. Antwort kann dieser Zeiger Offsets tun, here eine wiederverwendbare Makro:
macro_rules! offset_of {
($ty:ty, $field:ident) => {
&(*(0 as *const $ty)).$field as *const _ as usize
}
}
macro_rules! check_type_pair {
($a:expr, $b:expr) => {
if false {
let _type_check = if false {$a} else {$b};
}
}
}
macro_rules! parent_of_mut {
($child:expr, $ty:ty, $field:ident) => {
{
check_type_pair!(&(*(0 as *const $ty)).$field, &$child);
let offset = offset_of!($ty, $field);
&mut *(((($child as *mut _) as usize) - offset) as *mut $ty)
}
}
}
macro_rules! parent_of {
($child:expr, $ty:ty, $field:ident) => {
{
check_type_pair!(&(*(0 as *const $ty)).$field, &$child);
let offset = offset_of!($ty, $field);
&*(((($child as *const _) as usize) - offset) as *const $ty)
}
}
}
diese Weise, wenn wir ein Feld in einer Struktur haben, können wir die übergeordnete Struktur wie diese:
fn some_method(&self) {
// Where 'self' is ParentStruct.field,
// access ParentStruct instance.
let parent = unsafe { parent_of!(self, ParentStruct, field) };
}
Das Makro check_type_pair
hilft, einfache Fehler zu vermeiden, bei denen self
und ParentStruct.field
nicht vom selben Typ sind. Es ist jedoch nicht idiotensicher, wenn zwei verschiedene Mitglieder in einer Struktur den gleichen Typ haben.
Haben Sie versucht, den Zeiger in einen Bytezeiger umzuwandeln? –
versucht, aber Cast ist nicht erlaubt - '' Casting '& MyStruct' als' * const u8' ist ungültig''. – ideasman42
Gut zu wissen, dass ich nicht der Einzige bin, der es versucht hat: D –