[−][src]Crate repr_offset
repr_offset
allows computing and safely using field offsets from types with a stable layout.
Currently only #[repr(C)]
/#[repr(C,packed)]
/#[repr(C,align)]
structs are supported.
Features
These are some of the features this library provides:
-
The
ReprOffset
derive macro, which outputs associated constants with the offsets of fields. -
Using the
FieldOffset
type (how offsets are represented), with methods for operating on a field through a pointer to the struct, including getting a reference(or pointer) to the field. -
Use the
unsafe_struct_field_offsets
macro as an alternative to theReprOffset
derive macro, most useful when the "derive" feature is disabled.
Dependencies
This library re-exports the ReprOffset
derive macro from the
repr_offset_derive
crate when the "derive" feature is enabled
(it's enabled is the default).
If you don't need the derive macro,
you can disable the default feature in the Cargo.toml file with
repr_offset = { version = "....", default_features = false }
,
making a clean compile of this crate take one to three seconds(depends on the machine).
Examples
Derivation
This example demonstrates:
-
Deriving the field offset constants with the
ReprOffset
derive macro. -
Moving out unaligned fields through a raw pointer.
use repr_offset::ReprOffset; use std::mem::ManuallyDrop; #[repr(C, packed)] #[derive(ReprOffset)] struct Packed{ x: u8, y: u64, z: String, } let mut this = ManuallyDrop::new(Packed{ x: 5, y: 8, z: "oh,hi".to_string(), }); let ptr: *mut Packed = &mut *this; unsafe{ assert_eq!( Packed::OFFSET_X.read(ptr), 5 ); assert_eq!( Packed::OFFSET_Y.read(ptr), 8 ); assert_eq!( Packed::OFFSET_Z.read(ptr), "oh,hi".to_string() ); }
Initialization
This example demonstrates how you can:
-
Use the
unsafe_struct_field_offsets
macro to declare associated constants with the field offsets. -
Initialize an uninitialized struct by passing a pointer to it.
This example only compiles since Rust 1.36 because it uses MaybeUninit
.
use std::mem::MaybeUninit; use repr_offset::{unsafe_struct_field_offsets, Aligned}; fn main(){ unsafe { let mut foo = MaybeUninit::uninit(); initialize_foo(foo.as_mut_ptr()); assert_eq!( foo.assume_init(), Foo{ name: "foo".to_string(), x: 13, y: 21 } ); } } /// Initializes a `Foo` through a raw pointer. /// /// # Safety /// /// Callers must pass a pointer to uninitialized memory with the /// size and alignment of `Foo` unsafe fn initialize_foo(this: *mut Foo){ Foo::OFFSET_NAME.raw_get_mut(this).write("foo".into()); Foo::OFFSET_X.raw_get_mut(this).write(13); Foo::OFFSET_Y.raw_get_mut(this).write(21); } #[repr(C)] #[derive(Debug, PartialEq)] pub struct Foo{ pub name: String, pub x: u32, pub y: u32, } // This macro is unsafe to invoke because you have to ensure that: // - All field types are listed,in declaration order. // - The `alignment` parameter is `Unaligned` if the struct is `#[repr(C,packed)]`, // and `Aligned` if it's not. unsafe_struct_field_offsets!{ alignment = Aligned, impl[] Foo { pub const OFFSET_NAME:String; pub const OFFSET_X:u32; pub const OFFSET_Y:u32; } }
Modules
docs | Miscelaneous documentation, and documentation for derive macros. |
for_examples | Types used for examples, |
offset_calc | Functions for calculating field offsets. |
utils | Miscelaneous functions. |
Macros
unsafe_struct_field_offsets | Declares a sequence of associated constants with the offsets of the listed fields. |
Structs
Aligned | A marker type representing that a |
FieldOffset | Represents the offset of a (potentially nested) field inside a type. |
Unaligned | A marker type representing that a |
Traits
Alignment | Marker trait for types that represents the alignment of a |
CombinePacking | Trait that combines two |
Type Definitions
CombinePackingOut | Combines two |
Derive Macros
ReprOffset | This derive macro is documented in here |