Previous: Complex Types, Up: Types [Index]

#### 2.3.7 Complex Type Example

This example demonstrates how to use complex types:

    #include <stdio.h>
    #include <ffi.h>
    #include <complex.h>

    void complex_fn(_Complex float cf,
                    _Complex double cd,
                    _Complex long double cld)
    {
      printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n",
             (float)creal (cf), (float)cimag (cf),
             (float)creal (cd), (float)cimag (cd),
             (float)creal (cld), (float)cimag (cld));
    }

    int main()
    {
      ffi_cif cif;
      ffi_type *args[3];
      void *values[3];
      _Complex float cf;
      _Complex double cd;
      _Complex long double cld;

      /* Initialize the argument info vectors */
      args[0] = &ffi_type_complex_float;
      args[1] = &ffi_type_complex_double;
      args[2] = &ffi_type_complex_longdouble;
      values[0] = &cf;
      values[1] = &cd;
      values[2] = &cld;

      /* Initialize the cif */
      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
                       &ffi_type_void, args) == FFI_OK)
        {
          cf = 1.0 + 20.0 * I;
          cd = 300.0 + 4000.0 * I;
          cld = 50000.0 + 600000.0 * I;
          /* Call the function */
          ffi_call(&cif, (void (*)(void))complex_fn, 0, values);
        }

      return 0;
    }

This is an example for defining a custom complex type descriptor for compilers that support them:

    /*
     * This macro can be used to define new complex type descriptors
     * in a platform independent way.
     *
     * name: Name of the new descriptor is ffi_type_complex_<name>.
     * type: The C base type of the complex type.
     */
    #define FFI_COMPLEX_TYPEDEF(name, type, ffitype)             \
      static ffi_type *ffi_elements_complex_##name [2] = {      \
        (ffi_type *)(&ffitype), NULL                             \
      };                                                        \
      struct struct_align_complex_##name {                      \
        char c;                                                  \
        _Complex type x;                                         \
      };                                                        \
      ffi_type ffi_type_complex_##name = {                      \
        sizeof(_Complex type),                                   \
        offsetof(struct struct_align_complex_##name, x),         \
        FFI_TYPE_COMPLEX,                                        \
        (ffi_type **)ffi_elements_complex_##name                 \
      }

    /* Define new complex type descriptors using the macro: */
    /* ffi_type_complex_sint */
    FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
    /* ffi_type_complex_uchar */
    FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);

The new type descriptors can then be used like one of the built-in type descriptors in the previous example.