How to define and implement interfaces

Defining interfaces
Implementing interfaces
Interface definition prerequisites
Interface properties
Overriding interface methods

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);
}