Reinterpret packed data which is already in memory?

You can use primitive types.

# define a type that acts like a "packed" 24-bit struct of x::UInt8, y::UInt16:
primitive type Foo 24 end

function Base.getproperty(foo::Foo, s::Symbol)
    # create a Ref so that we can get a pointer to the raw bytes;
    # I'm not sure if there is a nicer way (unless the primitive type has
    # the right size to be be reinterpreted as a UInt64 or similar)
    r = Ref(foo)
    GC.@preserve r begin
        if s === :x
            return unsafe_load(Ptr{UInt8}(Base.unsafe_convert(Ptr{Cvoid}, r)))
        elseif s === :y
            return unsafe_load(Ptr{UInt16}(Base.unsafe_convert(Ptr{Cvoid}, r)+1))
        end
    end
    error("unknown field $s")
end
Base.show(io::IO, foo::Foo) = print(io, "Foo(", foo.x, ',', foo.y, ')')

after which you can do:

julia> foodata = reinterpret(Foo, [0x01, 0x00, 0x10, 0x02, 0x00, 0x20])
2-element reinterpret(Foo, ::Array{UInt8,1}):
 Foo(1,4096)
 Foo(2,8192)

julia> foodata[2].y
0x2000
5 Likes