Next: , Previous: , 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 enums. 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]