## How to define and implement interfaces

## Defining interfaces

The theory behind how GObject interfaces work is given in the section called “Non-instantiable classed types: interfaces”; this section covers how to define and implement an interface.

The first step is to get the header right. This interface defines two methods:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /*
     * Copyright/Licensing information.
     */

    #ifndef __MAMAN_IBAZ_H__
    #define __MAMAN_IBAZ_H__

    #include <glib-object.h>

    G_BEGIN_DECLS

    #define MAMAN_TYPE_IBAZ maman_ibaz_get_type ()
    G_DECLARE_INTERFACE (MamanIbaz, maman_ibaz, MAMAN, IBAZ, GObject)

    struct _MamanIbazInterface
    {
      GTypeInterface parent_iface;

      void (*do_action) (MamanIbaz *self);
      void (*do_something) (MamanIbaz *self);
    };

    void maman_ibaz_do_action    (MamanIbaz *self);
    void maman_ibaz_do_something (MamanIbaz *self);

    G_END_DECLS

    #endif /* __MAMAN_IBAZ_H__ */

This code is the same as the code for a normal GType which derives from a GObject except for a few details:

- The `_GET_CLASS` function is called `_GET_IFACE` (and is defined by `G_DECLARE_INTERFACE`).

- The instance type, MamanIbaz is not fully defined: it is used merely as an abstract type which represents an instance of whatever object which implements the interface.

- The parent of the MamanIbazInterface is GTypeInterface, not GObjectClass.

The implementation of the MamanIbaz type itself is trivial:

- `G_DEFINE_INTERFACE` creates a `maman_ibaz_get_type` function which registers the type in the type system. The third argument is used to define a prerequisite interface (which we'll talk about more later). Just pass `0` for this argument when an interface has no prerequisite.

- `maman_ibaz_default_init` is expected to register the interface's signals if there are any (we will see a bit later how to use them).

- The interface methods `maman_ibaz_do_action` and `maman_ibaz_do_something` dereference the interface structure to access its associated interface function and call it.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);

    static void
    maman_ibaz_default_init (MamanIbazInterface *iface)
    {
        /* add properties and signals to the interface here */
    }

    void
    maman_ibaz_do_action (MamanIbaz *self)
    {
      g_return_if_fail (MAMAN_IS_IBAZ (self));

      MAMAN_IBAZ_GET_IFACE (self)->do_action (self);
    }

    void
    maman_ibaz_do_something (MamanIbaz *self)
    {
      g_return_if_fail (MAMAN_IS_IBAZ (self));

      MAMAN_IBAZ_GET_IFACE (self)->do_something (self);
    }