I have a struct which I need to convert to byte buffer. Currently I'm using bytemuck crate to get this done, but I'm getting an error
#[derive(bytemuck::NoUninit, Clone, Copy)]
#[repr(C)]
pub struct Data {
    pub msg_id: u16,
    pub id: [u8; 128],
    pub a: f64,
    pub b: f64,
    pub c: f64,
    pub d: f64,
    pub e: f64,
    pub f: f64,
    pub g: f64,
}
fn main() {
    
}
Error
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
 --> src/main.rs:3:12
  |
3 | pub struct Data {
  |            ^^^^
  |
  = note: source type: `Data` (1536 bits)
  = note: target type: `TypeWithoutPadding` (1488 bits)
For more information about this error, try `rustc --explain E0512`.
error: could not compile `playground` (bin "playground") due to previous error
You have 130 bytes of data followed by a f64, which has alignment 8. 130 mod 8 = 2, so (per the repr(C) layout rules) there will be padding bytes placed between id and a. Padding bytes are always uninitialized, so they do not qualify for being bytemuck::NoUninit.
You must change your struct declaration so that it actually does not have uninitialized bytes. In some cases, you could do this by reordering the fields, but here that would leave you with padding at the end of the struct (because in Rust, a type's size is always a multiple of its alignment). Therefore, you will have to insert 6 bytes of explicit “padding”, so that the total byte size of the fields before the first f64 is a multiple of 8:
pub struct Data {
    pub msg_id: u16,
    pub _padding: [u8; 6],
    pub id: [u8; 128],
    pub a: f64,
    pub b: f64,
    pub c: f64,
    pub d: f64,
    pub e: f64,
    pub f: f64,
    pub g: f64,
}
This _padding field can be set to [0; 6] or whatever value you like; the important thing is that the language considers it to have a specific value, not be uninitialized, which is the property that bytemuck::NoUninit requires.
Of course, if you can find a use for those extra bytes, or a way to remove 2 bytes, that's even better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With