Stream: helpdesk (published)

Topic: ✔ How to efficiently convert bytes into a struct?


view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 19:45):

Suppose I have a immutable struct with primitive fields (e.g., UInt8):

struct MyStruct
  field1::UInt8
  field2::UInt16
  ...
 end

What is the most efficient method to convert a vector of bytes like

bytes = read(io, 100)

into an instance of the struct?

Do I need to loop over the fields and reinterpret each byte?

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 20:15):

I tested with reinterpret(MyStruct, bytes) and it apparently works, but the result is a vector with a single instance. Any way to return just the instance?

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 20:24):

My current solution for future reference:

only(reinterpret(MySctruct, bytes))

view this post on Zulip Mosè Giordano (Nov 14 2025 at 21:00):

I'm away from computer, going by memory you can pass a custom type to read

view this post on Zulip Mosè Giordano (Nov 14 2025 at 21:03):

Probably <https://docs.julialang.org/en/v1/base/io-network/#Base.read!>

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:03):

That is my current solution above, right?

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:04):

Júlio Hoffimann said:

My current solution for future reference:

only(reinterpret(MySctruct, bytes))

This one :up:

view this post on Zulip Mosè Giordano (Nov 14 2025 at 21:04):

I said read, not reinterpret

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:05):

Didn't know read also supported this. Let me check...

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:06):

image.png

Would it be that method?

view this post on Zulip Mosè Giordano (Nov 14 2025 at 21:06):

Yes

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:07):

Regarding the endianness, how can I enforce ntoh to always convert from Big Endian?

view this post on Zulip Mosè Giordano (Nov 14 2025 at 21:07):

That wasn't what I linked actually because zulip messed up the exclamation mark, but that should work too

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:08):

If I need to enforce endianness, I need to read first with the original endianness, convert the endianess with ntoh, and then reinterpret?

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:08):

Or there is a direct method with just read + ntoh?

view this post on Zulip Mosè Giordano (Nov 14 2025 at 21:08):

Júlio Hoffimann said:

Regarding the endianness, how can I enforce ntoh to always convert from Big Endian?

If you need to invert the endianess you may have to first rest the raw bits, invert, and then reinterpret

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:09):

Yep, I think the reinterpret is the way to go then.

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:20):

Solution for future reference:

only(reinterpret(MyStruct, map(ntoh, bytes)))

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:34):

The solution above doesn't work. The fact that the file endianness is different than the host machine forces reading field-by-field, converting each field with ntoh and then combining fields into the final struct.

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 21:47):

The solution that actually works:

fields = map(fieldnames(MyStruct)) do field
  type = fieldtype(MyStruct, field)
  ntoh(read(io, type))
end
reinterpret(MyStruct, fields)

view this post on Zulip Notification Bot (Nov 14 2025 at 21:47):

Júlio Hoffimann has marked this topic as resolved.

view this post on Zulip Mason Protter (Nov 14 2025 at 22:01):

You could also do

ptr = convert(Ptr{MyType}, pointer(bytes))
unsafe_load(ptr)

view this post on Zulip Mason Protter (Nov 14 2025 at 22:05):

Make sure you're aware of julia's padding conventions though. E.g. your struct

struct MyStruct
  field1::UInt8
  field2::UInt16
 end

actually has padding between field1 and field2 to give it anlignment, so field2 is not the the 2nd and 3rd bytes of the array.

view this post on Zulip Júlio Hoffimann (Nov 14 2025 at 22:55):

Thank yo for sharing this alternative. I think I will go with the reinterpret approach as it is working well.


Last updated: Nov 27 2025 at 04:44 UTC