Dealing with complex C structure

Taking the approach from the doc:

You can get a near approximation of a union if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type.

That’s not too bad. Here’s a MWE:

/* test.c */
typedef struct abc
{
        union {
                unsigned int a;
                long b;
        } ab;
        int c;
} ABC, *ABCP;

ABC make1()
{
        ABC x;
        x.c = 1;
        x.ab.b = 2;
        return x;
}

ABC make2()
{
        ABC x;
        x.c = 1;
        x.ab.a = 2;
        return x;
}

Compile as usual:

$ gcc -fPIC -shared test.c -o libtest.so

In Julia, I can treat the union as a regular long variable (which is the largest in this example):

julia> const TEST = "/tmp/libtest.so"
"/tmp/libtest.so"

julia> x = ccall((:make1, TEST), ABC, ())
ABC(2, 1)

julia> y = ccall((:make2, TEST), ABC, ())
ABC(5815918277548834818, 1)

So the value returned by make2 is obviously messed up because I should be looking for the int rather than the long field. To correct that, I can do some bit twiddling (not my favorite but some people here like it :slight_smile: )

julia> UInt64(y.ab)
0x50b64adc00000002

julia> Int32(y.ab & 0x00000000ffffffff)
2

I really need a way to reinterpret the thing so perhaps I just go with a fixed size tuple.

julia> struct ABC2
         ab::NTuple{8, Cuchar}   # 8 bytes
         c::Int32
       end

julia> z = ccall((:make2, TEST), ABC2, ())
ABC2((0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), 1)

julia> reinterpret(Int32, collect(z.ab[1:4]))
1-element Array{Int32,1}:
 2

Next, I’ll try to reinterpret to another struct. Hopefully that will work.

Does this all make sense? Is there any better way to approach this?