[−][src]Macro repr_offset::unsafe_struct_field_offsets
Declares a sequence of associated constants with the offsets of the listed fields.
Safety
Callers must ensure that:
-
The type that the offsets are for is a
#[repr(C)]
struct. -
All field types are listed,in declaration order.
-
The
alignment
parameter isUnaligned
if the struct is#[repr(C,packed)]
, andAligned
if it's not.
Parameters
Self
The optional Self
parameter overrides which struct the FieldOffset
constants
(that this outputs) are an offset inside of.
alignment
The alignment
parameter can be either Aligned
or Unaligned
,
and describes whether the fields are aligned or potentially unaligned,
changing how fields are accessed in FieldOffset
methods.
usize_offsets
The optional usize_offsets
parameter determines whether type of the
generated constants is FieldOffset
or usize
.
The valid values for this parameter are:
- (not passing this parameter): The constants are
FieldOffset
s. false
: The constants areFieldOffset
s.true
: The constants areusize
s.
Examples
Syntax example
This demonstrates the macro being used with all of the syntax.
use repr_offset::{unsafe_struct_field_offsets, Aligned}; #[repr(C)] struct Bar<T: Copy, U>(T,U) where U: Clone; unsafe_struct_field_offsets!{ // Optional parameter. // Generic parameters from the impl block can be used here. Self = Bar<T, U>, alignment = Aligned, // Optional parameter. usize_offsets = false, impl[T: Copy, U] Bar<T, U> where[ U: Clone ] { pub const OFFSET_0: T; pub const OFFSET_1: U; } }
Unaligned struct example
This demonstrates how you can get a pointer to a field from a pointer to
a packed struct (it's UB to use references to fields here),
as well as a FieldOffset
method to replace packed fields.
use repr_offset::{unsafe_struct_field_offsets, Unaligned}; let mut bar = Bar{ mugs: 3, bottles: 5, table: "wooden".to_string() }; assert_eq!( replace_table_a(&mut bar, "metallic".to_string()), "wooden".to_string()); assert_eq!( replace_table_b(&mut bar, "granite".to_string()), "metallic".to_string()); assert_eq!( replace_table_b(&mut bar, "carbonite".to_string()), "granite".to_string()); fn replace_table_a(this: &mut Bar, replacement: String)-> String{ let ptr = Bar::OFFSET_TABLE.get_mut_ptr(this); unsafe{ let taken = ptr.read_unaligned(); ptr.write_unaligned(replacement); taken } } fn replace_table_b(this: &mut Bar, replacement: String)-> String{ Bar::OFFSET_TABLE.replace_mut(this, replacement) } #[repr(C,packed)] struct Bar{ mugs: u32, bottles: u16, table: String, } unsafe_struct_field_offsets!{ alignment = Unaligned, impl[] Bar { pub const OFFSET_MUGS: u32; pub const OFFSET_BOTTLES: u16; pub const OFFSET_TABLE: String; } }