Fix up GObject interface documentation

* Document how to override interfaces already implemented
   in a base class, and also call those base class implementations
   from a derived reimplementation.
 * Don't recomend people use base_init() style functions to
   initialize interface signals and properties, use default_init()
   aka class_init() instead (as G_DEFINE_INTERFACE() uses).
 * The above solves the interface init called multiple times
   problem, so remove some needless naysaying about that.
 * Document default_init() in the interface initialization discussion
 * Linkify more stuff.
 * Remove some crud and typos

https://bugzilla.gnome.org/show_bug.cgi?id=675504
This commit is contained in:
Stef Walter 2012-05-05 12:51:16 +02:00
parent 2cf9608d48
commit 3b0f1cc432
2 changed files with 313 additions and 141 deletions

View File

@ -322,8 +322,9 @@ GType maman_bar_get_type (void)
</para>
<para>
When having no special requirements you also can use the <function>G_DEFINE_TYPE</function>
macro:
If you have no special requirements you can use the
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
macro to define a class:
<programlisting>
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
</programlisting>
@ -688,7 +689,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
}
</programlisting>
<function>maman_ibaz_get_type</function> registers a type named <emphasis>MamanIBaz</emphasis>
<function>maman_ibaz_get_type</function> registers a type named <emphasis>MamanIbaz</emphasis>
which inherits from G_TYPE_INTERFACE. All interfaces must be children of G_TYPE_INTERFACE in the
inheritance tree.
</para>
@ -706,14 +707,13 @@ void maman_ibaz_do_action (MamanIbaz *self)
Once an interface type is registered, you must register implementations for these
interfaces. The function named <function>maman_baz_get_type</function> registers
a new GType named MamanBaz which inherits from <link linkend="GObject"><type>GObject</type></link> and which
implements the interface <type>MamanIBaz</type>.
implements the interface <type>MamanIbaz</type>.
<programlisting>
static void maman_baz_do_action (MamanIbaz *self)
{
g_print ("Baz implementation of IBaz interface Action.\n");
g_print ("Baz implementation of Ibaz interface Action.\n");
}
static void
baz_interface_init (gpointer g_iface,
gpointer iface_data)
@ -728,7 +728,7 @@ maman_baz_get_type (void)
static GType type = 0;
if (type == 0) {
const GTypeInfo info = {
sizeof (MamanBazInterface),
sizeof (MamanBazClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL, /* class_init */
@ -771,22 +771,38 @@ struct _GInterfaceInfo
};
</programlisting>
</para>
<para>
When having no special requirements you also can use the <function>G_DEFINE_INTERFACE</function> macro:
If you have no special requirements you can use the
<link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link> macro
to implement an interface:
<programlisting>
G_DEFINE_INTERFACE (MamanBaz, maman_baz, G_TYPE_OBJECT)
static void
maman_baz_do_action (MamanIbaz *self)
{
g_print ("Baz implementation of Ibaz interface Action.\n");
}
static void
maman_ibaz_interface_init (MamanIbazInterface *iface)
{
iface->do_action = maman_baz_do_action;
}
G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
maman_ibaz_interface_init));
</programlisting>
</para>
<sect2 id="gtype-non-instantiable-classed-init">
<title>Interface Initialization</title>
<para>
When an instantiable classed type which registered an interface
implementation is created for the first time, its class structure
is initialized following the process
described in <xref linkend="gtype-instantiable-classed"/>.
When an instantiable classed type which implements an interface
(either directly or by inheriting an implementation from a superclass)
is created for the first time, its class structure is initialized
following the process described in <xref linkend="gtype-instantiable-classed"/>.
After that, the interface implementations associated with
the type are initialized.
</para>
@ -802,28 +818,65 @@ G_DEFINE_INTERFACE (MamanBaz, maman_baz, G_TYPE_OBJECT)
</para>
<para>
Finally, the interface' most-derived <function>base_init</function> function and then
The interface's <function>base_init</function> function is called,
and then the interface's <function>default_init</function> is invoked.
Finally if the type has registered an implementation of the interface,
the implementation's <function>interface_init</function>
function are invoked. It is important to understand that if there are multiple
implementations of an interface the <function>base_init</function> and
<function>interface_init</function> functions will be
invoked once for each implementation initialized.
function is invoked. If there are multiple implementations of an
interface the <function>base_init</function> and
<function>interface_init</function> functions will be invoked once
for each implementation initialized.
</para>
<para>
It is thus common for base_init functions to hold a local static boolean variable
which makes sure that the interface type is initialized only once even if there are
multiple implementations of the interface:
It is thus recommended to use a <function>default_init</function> function to
initialize an interface. This function is called only once for the interface no
matter how many implementations there are. The
<function>default_init</function> function is declared by
<link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link>
which can be used to define the interface:
<programlisting>
static void
maman_ibaz_base_init (gpointer g_iface)
{
static gboolean initialized = FALSE;
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);
if (!initialized) {
/* create interface signals here. */
initialized = TRUE;
static void
maman_ibaz_default_init (MamanIbazInterface *iface)
{
/* add properties and signals here, will only called once */
}
</programlisting>
</para>
<para>
Or you can do that yourself in a GType function for your interface:
<programlisting>
GType
maman_ibaz_get_type (void)
{
static volatile gsize type_id = 0;
if (g_once_init_enter (&amp;type_id)) {
const GTypeInfo info = {
sizeof (MamanIbazInterface),
NULL, /* base_init */
NULL, /* base_finalize */
maman_ibaz_default_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
0, /* instance_size */
0, /* n_preallocs */
NULL /* instance_init */
};
GType type = g_type_register_static (G_TYPE_INTERFACE,
"MamanIbaz",
&amp;info, 0);
g_once_init_leave (&amp;type_id, type);
}
return type_id;
}
static void
maman_ibaz_default_init (MamanIbazInterface *iface)
{
/* add properties and signals here, will only called once */
}
</programlisting>
</para>
@ -835,7 +888,6 @@ maman_ibaz_base_init (gpointer g_iface)
</para>
<para>
The above process can be summarized as follows:
<table id="ginterface-init-table">
<title>Interface Initialization</title>
<tgroup cols="3">
@ -853,24 +905,31 @@ maman_ibaz_base_init (gpointer g_iface)
</thead>
<tbody>
<row>
<entry morerows="1">First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for type
implementing interface
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
for <emphasis>any</emphasis> type implementing interface
</entry>
<entry>interface' base_init function</entry>
<entry>On interface' vtable</entry>
<entry>Register interface' signals here (use a local static
boolean variable as described above to make sure not to register them
twice.).</entry>
<entry>interface's <function>base_init</function> function</entry>
<entry>On interface's vtable</entry>
<entry>Rarely necessary to use this. Called once per instantiated classed type implementing the interface.</entry>
</row>
<row>
<!--entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for type
implementing interface
</entry-->
<entry>interface' interface_init function</entry>
<entry>On interface' vtable</entry>
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
for <emphasis>each</emphasis> type implementing interface
</entry>
<entry>interface's <function>default_init</function> function</entry>
<entry>On interface's vtable</entry>
<entry>Register interface's signals, properties, etc. here. Will be called once.</entry>
</row>
<row>
<entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
for <emphasis>any</emphasis> type implementing interface
</entry>
<entry>implementation's <function>interface_init</function> function</entry>
<entry>On interface's vtable</entry>
<entry>
Initialize interface' implementation. That is, initialize the interface
method pointers in the interface structure to the function's implementation.
Initialize interface implementation. Called for each class that that
implements the interface. Initialize the interface method pointers
in the interface structure to the implementing class's implementation.
</entry>
</row>
</tbody>

View File

@ -794,7 +794,7 @@ b_method_to_call (B *obj, int a)
<title>How to define and implement interfaces</title>
<sect1 id="howto-interface-define">
<title>How to define interfaces</title>
<title>How to define an interface</title>
<para>
The bulk of interface definition has already been shown in <xref linkend="gtype-non-instantiable-classed"/>
@ -802,7 +802,8 @@ b_method_to_call (B *obj, int a)
</para>
<para>
As above, the first step is to get the header right:
As above, the first step is to get the header right. This interface
defines two methods:
<programlisting>
#ifndef __MAMAN_IBAZ_H__
#define __MAMAN_IBAZ_H__
@ -823,11 +824,13 @@ struct _MamanIbazInterface
GTypeInterface parent_iface;
void (*do_action) (MamanIbaz *self);
void (*do_something) (MamanIbaz *self);
};
GType maman_ibaz_get_type (void);
void maman_ibaz_do_action (MamanIbaz *self);
void maman_ibaz_do_action (MamanIbaz *self);
void maman_ibaz_do_something (MamanIbaz *self);
#endif /* __MAMAN_IBAZ_H__ */
</programlisting>
@ -854,51 +857,28 @@ void maman_ibaz_do_action (MamanIbaz *self);
<para>
The implementation of the <type>MamanIbaz</type> type itself is trivial:
<itemizedlist>
<listitem><para><function>maman_ibaz_get_type</function> registers the
type in the type system.
<listitem><para><function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
creates a <function>maman_ibaz_get_type</function> function which registers the
type in the type system. The third argument is used to define a
<link linkend="howto-interface-prerequisite">prerequisite interface</link>
(which we'll talk about more later). Just pass <code>0</code> for this
argument when an interface has no prerequisite.
</para></listitem>
<listitem><para><function>maman_ibaz_base_init</function> is expected
<listitem><para><function>maman_ibaz_default_init</function> is expected
to register the interface's signals if there are any (we will see a bit
(later how to use them). Make sure to use a static local boolean variable
to make sure not to run the initialization code twice (as described in
<xref linkend="gtype-non-instantiable-classed-init"/>,
<function>base_init</function> is run once for each interface implementation
instantiation)</para></listitem>
<listitem><para><function>maman_ibaz_do_action</function> dereferences
the class structure to access its associated class function and calls it.
later how to use them).</para></listitem>
<listitem><para>The interface methods <function>maman_ibaz_do_action</function>
and <function>maman_ibaz_do_something</function> dereference the interface
structure to access its associated interface function and call it.
</para></listitem>
</itemizedlist>
<programlisting>
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, 0);
static void
maman_ibaz_base_init (gpointer g_class)
maman_ibaz_default_init (gpointer g_class)
{
static gboolean is_initialized = FALSE;
if (!is_initialized)
{
/* add properties and signals to the interface here */
is_initialized = TRUE;
}
}
GType
maman_ibaz_get_type (void)
{
static GType iface_type = 0;
if (iface_type == 0)
{
const GTypeInfo info = {
sizeof (MamanIbazInterface),
maman_ibaz_base_init, /* base_init */
NULL, /* base_finalize */
};
iface_type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbaz",
&amp;info, 0);
}
return iface_type;
/* add properties and signals to the interface here */
}
void
@ -908,12 +888,20 @@ maman_ibaz_do_action (MamanIbaz *self)
MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
}
void
maman_ibaz_do_something (MamanIbaz *self)
{
g_return_if_fail (MAMAN_IS_IBAZ (self));
MAMAN_IBAZ_GET_INTERFACE (self)->do_something (self);
}
</programlisting>
</para>
</sect1>
<sect1 id="howto-interface-implement">
<title>How To define implement an Interface?</title>
<title>How to implement an interface</title>
<para>
Once the interface is defined, implementing it is rather trivial.
@ -954,15 +942,22 @@ GType maman_baz_get_type (void);
#endif /* __MAMAN_BAZ_H__ */
</programlisting>
<!-- Ha ha! "nothing weird or scary". I actually laughed out loud. Oh boy.
The fact that we're so intimate with GObject that all this doesn't look
wierd, that's the scary thing. :) -->
There is clearly nothing specifically weird or scary about this header:
it does not define any weird API or derives from a weird type.
it does not define any weird API or derive from a weird type.
</para>
<para>
The second step is to implement <type>MamanBaz</type> by defining
its GType. Instead of using <function>G_DEFINE_TYPE</function> we
use <function>G_DEFINE_TYPE_WITH_CODE</function> and the
<function>G_IMPLEMENT_INTERFACE</function> macros.
its GType. Instead of using
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
we use
<function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
and the
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
macros.
<programlisting>
static void maman_ibaz_interface_init (MamanIbazInterface *iface);
@ -971,13 +966,15 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
maman_ibaz_interface_init));
</programlisting>
This definition is very much like all the similar functions we looked
at previously. The only interface-specific code present here is the call
to <function>G_IMPLEMENT_INTERFACE</function>.
at previously. The only interface-specific code present here is the call to
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>.
</para>
<note><para>Classes can implement multiple interfaces by using multiple
calls to <function>G_IMPLEMENT_INTERFACE</function> inside the call
to <function>G_DEFINE_TYPE_WITH_CODE</function>.</para></note>
<note><para>Classes can implement multiple interfaces by using multiple calls to
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
inside the call to
<function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
</para></note>
<para>
<function>maman_baz_interface_init</function>, the interface
@ -987,14 +984,22 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
static void
maman_baz_do_action (MamanBaz *self)
{
g_print ("Baz implementation of IBaz interface Action: 0x%x.\n",
g_print ("Baz implementation of Ibaz interface Action: 0x%x.\n",
self->instance_member);
}
static void
maman_baz_do_something (MamanBaz *self)
{
g_print ("Baz implementation of Ibaz interface Something: 0x%x.\n",
self->instance_member);
}
static void
maman_ibaz_interface_init (MamanIbazInterface *iface)
{
iface->do_action = baz_do_action;
iface->do_action = maman_baz_do_action;
iface->do_something = maman_baz_do_something;
}
static void
@ -1005,17 +1010,16 @@ maman_baz_init (MamanBaz *self)
}
</programlisting>
</para>
</sect1>
<sect1>
<sect1 id="howto-interface-prerequisite">
<title>Interface definition prerequisites</title>
<para>
To specify that an interface requires the presence of other interfaces
when implemented, GObject introduces the concept of
<emphasis>prerequisites</emphasis>: it is possible to associate
a list of prerequisite interfaces to an interface. For example, if
a list of prerequisite types to an interface. For example, if
object A wishes to implement interface I1, and if interface I1 has a
prerequisite on interface I2, A has to implement both I1 and I2.
</para>
@ -1025,16 +1029,15 @@ maman_baz_init (MamanBaz *self)
Java's interface I1 extends interface I2. The example below shows
the GObject equivalent:
<programlisting>
/* inside the GType function of the MamanIbar interface */
type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbar", &amp;info, 0);
/* Make the MamanIbar interface require MamanIbaz interface. */
g_type_interface_add_prerequisite (type, MAMAN_TYPE_IBAZ);
/* Make the MamanIbar interface require MamanIbaz interface. */
G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ);
</programlisting>
The code shown above adds the MamanIbaz interface to the list of
prerequisites of MamanIbar while the code below shows how an
implementation can implement both interfaces and register their
implementations:
In the <function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
call above, the third parameter defines the prerequisite type. This
is the GType of either an interface or a class. In this case
the MamanIbaz interface is a prerequisite of the MamanIbar. The code
below shows how an implementation can implement both interfaces and
register their implementations:
<programlisting>
static void
maman_ibar_do_another_action (MamanIbar *ibar)
@ -1056,7 +1059,16 @@ maman_ibaz_do_action (MamanIbaz *ibaz)
{
MamanBar *self = MAMAN_BAR (ibaz);
g_print ("Bar implementation of IBaz interface Action: 0x%x.\n",
g_print ("Bar implementation of Ibaz interface Action: 0x%x.\n",
self->instance_member);
}
static void
maman_ibaz_do_something (MamanIbaz *ibaz)
{
MamanBar *self = MAMAN_BAR (ibaz);
g_print ("Bar implementation of Ibaz interface Something: 0x%x.\n",
self->instance_member);
}
@ -1064,6 +1076,7 @@ static void
maman_ibaz_interface_init (MamanIbazInterface *iface)
{
iface->do_action = maman_ibaz_do_action;
iface->do_something = maman_ibaz_do_something;
}
static void
@ -1087,22 +1100,24 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
It is very important to notice that the order in which interface
implementations are added to the main object is not random:
<function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function>,
which is called by <function>G_IMPLEMENT_INTERFACE</function>, must be
invoked first on the interfaces which have no prerequisites and then on
which is called by
<function><link linkend="G-DEFINE-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>,
must be invoked first on the interfaces which have no prerequisites and then on
the others.
</para>
</sect1>
<sect1 id="howto-interface-properties">
<title>Interface Properties</title>
<title>Interface properties</title>
<para>
Starting from version 2.4 of GLib, GObject interfaces can also have
GObject interfaces can also have
properties. Declaration of the interface properties is similar to
declaring the properties of ordinary GObject types as explained in
<xref linkend="gobject-properties"/>,
except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to
declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
<xref linkend="gobject-properties"/>, except that
<function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function>
is used to declare the properties instead of
<function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
</para>
<para>
@ -1114,31 +1129,17 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
That really is one line extended to six for the sake of clarity
</para>
</footnote>
line in the <function>maman_ibaz_base_init</function>
<footnote>
<para>
The <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function>
can also be called from <function>class_init</function> but it must
not be called after that point.
</para>
</footnote>
as shown below:
line in the <function>maman_ibaz_default_init</function> as shown below:
<programlisting>
static void
maman_ibaz_base_init (gpointer g_iface)
maman_ibaz_default_init (gpointer g_iface)
{
static gboolean is_initialized = FALSE;
if (!is_initialized)
{
g_object_interface_install_property (g_iface,
g_param_spec_string ("name",
"Name",
"Name of the MamanIbaz",
"maman",
G_PARAM_READWRITE));
is_initialized = TRUE;
}
g_object_interface_install_property (g_iface,
g_param_spec_string ("name",
"Name",
"Name of the MamanIbaz",
"maman",
G_PARAM_READWRITE));
}
</programlisting>
</para>
@ -1152,9 +1153,9 @@ maman_ibaz_base_init (gpointer g_iface)
</para>
<para>
An implementation shall declare and define it's properties in the usual
An implementation declares and defines it's properties in the usual
way as explained in <xref linkend="gobject-properties"/>, except for one
small change: it must declare the properties of the interface it
small change: it can declare the properties of the interface it
implements using <function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function>
instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
The following code snippet shows the modifications needed in the
@ -1233,6 +1234,118 @@ maman_baz_class_init (MamanBazClass *klass)
</para>
</sect1>
<sect1 id="howto-interface-override">
<title>Overriding interface methods</title>
<para>
If a base class already implements an interface, and in a derived
class you wish to implement the same interface overriding only certain
methods of that interface, you just reimplement the interface and
set only the interface methods you wish to override.
</para>
<para>
In this example MamanDerivedBaz is derived from MamanBaz. Both
implement the MamanIbaz interface. MamanDerivedBaz only implements one
method of the MamanIbaz interface and uses the base class implementation
of the other.
<programlisting>
static void
maman_derived_ibaz_do_action (MamanIbaz *ibaz)
{
MamanDerivedBaz *self = MAMAN_DERIVED_BAZ (ibaz);
g_print ("DerivedBaz implementation of Ibaz interface Action\n");
}
static void
maman_derived_ibaz_interface_init (MamanIbazInterface *iface)
{
/* Override the implementation of do_action */
iface->do_action = maman_derived_ibaz_do_action;
/*
* We simply leave iface->do_something alone, it is already set to the
* base class implementation.
*/
}
G_DEFINE_TYPE_WITH_CODE (MamanDerivedBaz, maman_derived_baz, MAMAN_TYPE_BAZ,
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
maman_derived_ibaz_interface_init)
static void
maman_derived_baz_class_init (MamanDerivedBazClass *klass)
{
}
static void
maman_derived_baz_init (MamanDerivedBaz *self)
{
}
</programlisting>
</para>
<para>
To access the base class interface implementation use
<function><link linkend="g-type-interface-peek-parent">g_type_interface_peek_parent</link></function>
from within an interface's <function>default_init</function> function.
</para>
<para>
If you wish to call the base class implementation of an interface
method from an derived class where than interface method has been
overridden then you can stash away the pointer returned from
<function><link linkend="g-type-interface-peek-parent">g_type_interface_peek_parent</link></function>
in a global variable.
</para>
<para>
In this example MamanDerivedBaz overides the
<function>do_action</function> interface method. In it's overridden method
it calls the base class implementation of the same interface method.
<programlisting>
static MamanIbazInterface *maman_ibaz_parent_interface = NULL;
static void
maman_derived_ibaz_do_action (MamanIbaz *ibaz)
{
MamanDerivedBaz *self = MAMAN_DERIVED_BAZ (ibaz);
g_print ("DerivedBaz implementation of Ibaz interface Action\n");
/* Now we call the base implementation */
maman_ibaz_parent_interface->do_action (ibaz);
}
static void
maman_derived_ibaz_interface_init (MamanIbazInterface *iface)
{
maman_ibaz_parent_interface = g_type_interface_peek_parent (iface);
iface->do_action = maman_derived_ibaz_do_action;
}
G_DEFINE_TYPE_WITH_CODE (MamanDerivedBaz, maman_derived_baz, MAMAN_TYPE_BAZ,
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
maman_derived_ibaz_interface_init)
static void
maman_derived_baz_class_init (MamanDerivedBazClass *klass)
{
}
static void
maman_derived_baz_init (MamanDerivedBaz *self)
{
}
</programlisting>
</para>
</sect1>
</chapter>
<!-- End Howto Interfaces -->