Next: Type Example, Previous: Size and Alignment, Up: Types [Index]

#### 2.3.4 Arrays, Unions, and Enumerations

#### 2.3.4.1 Arrays

`libffi` does not have direct support for arrays or unions. However, they can be emulated using structures.

To emulate an array, simply create an `ffi_type` using `FFI_TYPE_STRUCT` with as many members as there are elements in the array.

    ffi_type array_type;
    ffi_type **elements
    int i;

    elements = malloc ((n + 1) * sizeof (ffi_type *));
    for (i = 0; i < n; ++i)
      elements[i] = array_element_type;
    elements[n] = NULL;

    array_type.size = array_type.alignment = 0;
    array_type.type = FFI_TYPE_STRUCT;
    array_type.elements = elements;

Note that arrays cannot be passed or returned by value in C – structure types created like this should only be used to refer to members of real `FFI_TYPE_STRUCT` objects.

However, a phony array type like this will not cause any errors from `libffi` if you use it as an argument or return type. This may be confusing.

#### 2.3.4.2 Unions

A union can also be emulated using `FFI_TYPE_STRUCT`. In this case, however, you must make sure that the size and alignment match the real requirements of the union.

One simple way to do this is to ensue that each element type is laid out. Then, give the new structure type a single element; the size of the largest element; and the largest alignment seen as well.

This example uses the `ffi_prep_cif` trick to ensure that each element type is laid out.

    ffi_abi desired_abi;
    ffi_type union_type;
    ffi_type **union_elements;

    int i;
    ffi_type element_types[2];

    element_types[1] = NULL;

    union_type.size = union_type.alignment = 0;
    union_type.type = FFI_TYPE_STRUCT;
    union_type.elements = element_types;

    for (i = 0; union_elements[i]; ++i)
      {
        ffi_cif cif;
        if (ffi_prep_cif (&cif, desired_abi, 0, union_elements[i], NULL) == FFI_OK)
          {
            if (union_elements[i]->size > union_type.size)
              {
                union_type.size = union_elements[i];
                size = union_elements[i]->size;
              }
            if (union_elements[i]->alignment > union_type.alignment)
              union_type.alignment = union_elements[i]->alignment;
          }
      }

#### 2.3.4.3 Enumerations

`libffi` does not have any special support for C `enum`s. Although any given `enum` is implemented using a specific underlying integral type, exactly which type will be used cannot be determined by `libffi` – it may depend on the values in the enumeration or on compiler flags such as `-fshort-enums`. See (gcc)Structures unions enumerations and bit-fields implementation, for more information about how GCC handles enumerations.

Next: Type Example, Previous: Size and Alignment, Up: Types [Index]