# Change endianness in reinterpret

Hello!

I am trying to reinterpret a `Vector` of bytes into a predefined type I have. However, primitive types are always intepreted as being little endian. Is there any way I can change this?

MWE:

``````julia> struct P
a::UInt32
b::UInt8
c::UInt8
d::UInt16
end

julia> struct Q
a::UInt32
b::UInt32
end

julia> a = [0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08]

julia> reinterpret(P,a)
1-element reinterpret(P, ::Vector{UInt8}):
P(0x04030201, 0x05, 0x06, 0x0807)

julia> reinterpret(Q,a)
1-element reinterpret(Q, ::Vector{UInt8}):
Q(0x04030201, 0x08070605)
``````

Can I get inner integers to be `0x01020304` and so on?

Thanks!

There might be a more elegant way, but this works:

``````Q((hton(getfield(only(reinterpret(Q, a)), f)) for f in fieldnames(Q))...)
``````
1 Like

Yep, I had already thought of that. However, the solution gets more complicated when, instead of `a` and `b` being easy `UInt` types, they become more complex. For example, something along the lines of:

``````julia> struct Q
a::UInt32
b::UInt32
end
julia> struct P
a::Q
b::UInt8
c::UInt8
d::UInt16
end
``````

In this case, the algorithm must be recursive and, although possible, it becomes a pain in the ass

You could automate writing a recursive `ntoh` method for your struct with a macro or similar, but unless you have a lot of such structs (or a lot of struct fields), it’s probably easier to just write `ntoh` methods by hand:

``````Base.ntoh(x::Q) = Q(ntoh(x.a), ntoh(x.b))
Base.ntoh(x::P) = P(ntoh(x.a), ntoh(x.b), ntoh(x.c), ntoh(x.d))
``````

Then just do `ntoh.(reinterpret(P, bytes))`.

To define both `ntoh` and `hton`, you can use a simpler metaprogramming trick:

``````for f in (:ntoh, :hton)
@eval Base.\$f(x::Q) = Q(\$f(x.a), \$f(x.b))
@eval Base.\$f(x::P) = P(\$f(x.a), \$f(x.b), \$f(x.c), \$f(x.d))
end
``````
6 Likes