cunionsffilibffi

How do I create an `ffi_type` that represents a union?


I'm using libffi to call a function that expects a union type argument.

I'm not sure exactly what the rules are for creating an ffi_type struct describing a union type. For example, if I have this:

union Vector4
{
    struct { float x, y, z, w; };
    struct { float r, g, b, a; };
    struct { float s, t, p, q; };
    float v[4];
}

What's the correct structure for ffi_type?


Solution

  • libffi does not have direct support for unions, but it can be emulated using a trick:

    First, make an ffi_type for each element of the union. Use ffi_prep_cif for its side-effect of laying out the type. (You can use ffi_get_struct_offsets as well, but that's very new.)

    Next, make the union type as an FFI_TYPE_STRUCT. Give it a single member -- but make sure it is the largest type from the first step. Also, make sure this member has the strictest (largest) alignment of all the alignments from the first step (you can do this by manually setting the alignment).

    This faked-up type is your union type.

    There is at least one bug report in the libffi tracker saying that this trick doesn't work for some ABIs. As far as I know nobody has investigated whether this is true; but if so it argues for adding real union support directly in libffi.