I've got a struct which looks like this:
#[repr(packed)]
struct Header {
some: u8,
thing: u8,
}
How can I get raw bytes from it, that I could use for either a C library or socket interaction?
I was hoping to use transmute
to solve the problem, but unfortunately this doesn't work:
let header = Header {....}
let header_bytes: &[u8] = unsafe { mem::transmute(header) };
let result = self.socket.write(header_bytes);
This fails with
error: transmute called on types with different sizes: &Header (64 bits) to &[u8] (128 bits)
Edit: updated for Rust 1.x.
You can't transmute arbitrary thing to arbitrary thing (like Header
to &[u8]
) because transmute()
is akin to reinterpret_cast
in C++: it literally reinterprets the bytes which its argument consists of, and in order for this to be successful the source and the target type should have the same size. But even if Header
and &[u8]
had the same size, it wouldn't make sense to convert between them: Header
is an actual value while &[u8]
is a pointer with a size of data behind that pointer.
In order to interpret a piece of data as a slice of bytes you need to perform three steps: obtain a raw pointer to the data, convert it to a pointer to u8
and then convert that to a slice of u8
. This means enhancing the raw pointer value with the length, which in this case is equal to the structure size. The last step can easily be done with std::slice::from_raw_parts()
:
use std::slice;
use std::mem;
let p: *const Header = &header; // the same operator is used as with references
let p: *const u8 = p as *const u8; // convert between pointer types
let s: &[u8] = unsafe {
slice::from_raw_parts(p, mem::size_of::<Header>())
};
However, doing this in most cases is not a good idea. Even though the struct is marked as packed, it still leaves the problem with the byte order, so at the very least the code which does this won't be portable (or rather, the data it serializes in such form may not be recoverable by the same program compiled for another architecture).
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