[][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 the ReprOffset 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 is for an aligned field.

FieldOffset

Represents the offset of a (potentially nested) field inside a type.

Unaligned

A marker type representing that a FieldOffset is for a (potentially) unaligned field.

Traits

Alignment

Marker trait for types that represents the alignment of a FieldOffset.

CombinePacking

Trait that combines two Alignment types, determines the return type of FieldOffset + FieldOffset.

Type Definitions

CombinePackingOut

Combines two Alignment types, determines the return type of FieldOffset + FieldOffset.

Derive Macros

ReprOffset

This derive macro is documented in here