#Copy struct to mem and print out as hex

1 messages · Page 1 of 1 (latest)

fervent trout
#

I am trying to play with a simple binary based protocol over tcp. I want to send a simple struct to my client when i connect but am having trouble figuring out how i can print the struct to []u8.


    const MyStruct = struct {
        a: u8,
        b: u16,
        c: u32,
    };
    var my_struct = MyStruct{ .a = 1, .b = 2, .c = 3 };
    _ = my_struct;

    var buffer: [@sizeOf(MyStruct)]u8 = undefined;
    _ = buffer;

    std.mem.copy(???)
frigid herald
#

@memcpy(&buffer, @as([*]const u8, @ptrCast(&mystruct)));

abstract knot
#

To get the bytes of a struct as a slice you can use std.mem.asBytes(&mystruct).

You probably don't want to use this to send a struct over the network though because Zig doesn't guarantee field order/memory layout of structs (you could fix this by using extern struct though), and the endianness of integers might differ between the two TCP clients.

I would look at serialization.

tiny wind
#

Even extern struct wont save you if the other side doesn't have the same architecture

#

I think?

abstract knot
#

Yeah, maybe you're right. It's just guaranteed to match C ABI on the target arch.

fervent trout
#

What would you recommend for serialization over the wire? That is part of the standard lib.

fickle bramble
#

That said - there is std.io.Writer.writeStruct, but it literally just sends the bytes over the wire.

fervent trout
#

Thanks for the responses. How would I then convert the u8 array back into the MyStruct struct?

abstract knot
#

const mystruct: *MyStruct = @ptrCast(byte_slice);

hollow heart
#

ont worry abnout endianness - nothing is little endian anymore

abstract knot
#

Do you mean nothing is big endian?

hollow heart
#

probably I have to stop and think which is which whewn i talk about it BC I NEVER HAVE TO WORRY ABOUT IT and I write a ton of netwroking code

fickle bramble
fervent trout
#

Thanks, @abstract knot 's suggestion also worked, I assume they are similar under the hood?

hollow heart
#

Are there any rules concerning the padding in those structs? Rust has some pretty severe restrictions on doing anthing with the padding since it can be garbage so byte and struct comparisons can do weird things when paddign is involved..

grizzled pike
#

Your best bet, and what has worked for me the most reliably is to conform to platform-specific C ABIs. For cross-platform, implement them separately because Linux and Windows each have their idiosyncrasies.

You can have padding bytes to help align fields if you need to (or to skip fields you simply dont need), but you need to specify the layout of the memory so the compiler does not re-order your fields, as mentioned above by others.