~ubuntu-branches/ubuntu/utopic/glib2.0/utopic

« back to all changes in this revision

Viewing changes to docs/reference/gobject/html/gtype-non-instantiable-classed.html

Tags: upstream-2.12.12
ImportĀ upstreamĀ versionĀ 2.12.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
2
<html>
 
3
<head>
 
4
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
 
5
<title>Non-instantiable classed types: Interfaces.</title>
 
6
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
 
7
<link rel="start" href="index.html" title="GObject Reference Manual">
 
8
<link rel="up" href="ch02.html" title="The Glib Dynamic Type System">
 
9
<link rel="prev" href="gtype-instantiable-classed.html" title="Instantiable classed types: objects">
 
10
<link rel="next" href="chapter-gobject.html" title="The GObject base class">
 
11
<meta name="generator" content="GTK-Doc V1.7 (XML mode)">
 
12
<link rel="stylesheet" href="style.css" type="text/css">
 
13
<link rel="preface" href="pr01.html" title="Introduction">
 
14
<link rel="part" href="pt01.html" title="Part&#160;I.&#160;Concepts">
 
15
<link rel="chapter" href="ch01.html" title="Background">
 
16
<link rel="chapter" href="ch02.html" title="The Glib Dynamic Type System">
 
17
<link rel="chapter" href="chapter-gobject.html" title="The GObject base class">
 
18
<link rel="chapter" href="chapter-signal.html" title="The GObject messaging system">
 
19
<link rel="reference" href="rn01.html" title="API Reference">
 
20
<link rel="reference" href="rn02.html" title="Tools Reference">
 
21
<link rel="part" href="pt02.html" title="Part&#160;IV.&#160;Tutorial">
 
22
<link rel="chapter" href="howto-gobject.html" title="How To define and implement a new GObject?">
 
23
<link rel="chapter" href="howto-interface.html" title="How To define and implement Interfaces?">
 
24
<link rel="chapter" href="howto-signals.html" title="Howto create and use signals">
 
25
<link rel="part" href="pt03.html" title="Part&#160;V.&#160;Related Tools">
 
26
<link rel="chapter" href="tools-gob.html" title="GObject builder">
 
27
<link rel="chapter" href="tools-ginspector.html" title="Graphical inspection of Gobjects">
 
28
<link rel="chapter" href="tools-refdb.html" title="Debugging reference count problems">
 
29
<link rel="chapter" href="tools-gtkdoc.html" title="Writing API docs">
 
30
<link rel="index" href="ix01.html" title="Index">
 
31
<link rel="index" href="ix02.html" title="Index of deprecated symbols">
 
32
<link rel="index" href="ix03.html" title="Index of new symbols in 2.2">
 
33
<link rel="index" href="ix04.html" title="Index of new symbols in 2.4">
 
34
<link rel="index" href="ix05.html" title="Index of new symbols in 2.6">
 
35
<link rel="index" href="ix06.html" title="Index of new symbols in 2.8">
 
36
<link rel="index" href="ix07.html" title="Index of new symbols in 2.10">
 
37
<link rel="index" href="ix08.html" title="Index of new symbols in 2.12">
 
38
</head>
 
39
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
 
40
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
 
41
<td><a accesskey="p" href="gtype-instantiable-classed.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
 
42
<td><a accesskey="u" href="ch02.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
 
43
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
 
44
<th width="100%" align="center">GObject Reference Manual</th>
 
45
<td><a accesskey="n" href="chapter-gobject.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
 
46
</tr></table>
 
47
<div class="sect1" lang="en">
 
48
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
 
49
<a name="gtype-non-instantiable-classed"></a>Non-instantiable classed types: Interfaces.</h2></div></div></div>
 
50
<p>
 
51
          GType's Interfaces are very similar to Java's interfaces. To declare one of these
 
52
          you have to register a non-instantiable classed type which derives from 
 
53
          <span class="type"><a href="gobject-Type-Information.html#GTypeInterface">GTypeInterface</a></span>. The following piece of code declares such an interface.
 
54
</p>
 
55
<pre class="programlisting">
 
56
#define MAMAN_IBAZ_TYPE                (maman_ibaz_get_type ())
 
57
#define MAMAN_IBAZ(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz))
 
58
#define MAMAN_IS_IBAZ(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_IBAZ_TYPE))
 
59
#define MAMAN_IBAZ_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_IBAZ_TYPE, MamanIbazInterface))
 
60
 
 
61
typedef struct _MamanIbaz MamanIbaz; /* dummy object */
 
62
typedef struct _MamanIbazInterface MamanIbazInterface;
 
63
 
 
64
struct _MamanIbazInterface {
 
65
  GTypeInterface parent;
 
66
 
 
67
  void (*do_action) (MamanIbaz *self);
 
68
};
 
69
 
 
70
GType maman_ibaz_get_type (void);
 
71
 
 
72
void maman_ibaz_do_action (MamanIbaz *self);
 
73
</pre>
 
74
<p>
 
75
          The interface function, <code class="function">maman_ibaz_do_action</code> is implemented
 
76
          in a pretty simple way:
 
77
</p>
 
78
<pre class="programlisting">
 
79
void maman_ibaz_do_action (MamanIbaz *self)
 
80
{
 
81
  MAMAN_IBAZ_GET_INTERFACE (self)-&gt;do_action (self);
 
82
}
 
83
</pre>
 
84
<p>
 
85
         <code class="function">maman_ibaz_get_type</code> registers a type named <span class="emphasis"><em>MamanIBaz</em></span>
 
86
         which inherits from G_TYPE_INTERFACE. All interfaces must be children of G_TYPE_INTERFACE in the 
 
87
         inheritance tree.
 
88
        </p>
 
89
<p>
 
90
          An interface is defined by only one structure which must contain as first member
 
91
          a <span class="type"><a href="gobject-Type-Information.html#GTypeInterface">GTypeInterface</a></span> structure. The interface structure is expected to
 
92
          contain the function pointers of the interface methods. It is good style to 
 
93
          define helper functions for each of the interface methods which simply call
 
94
          the interface' method directly: <code class="function">maman_ibaz_do_action</code>
 
95
          is one of these.
 
96
        </p>
 
97
<p>
 
98
          Once an interface type is registered, you must register implementations for these
 
99
          interfaces. The function named <code class="function">maman_baz_get_type</code> registers
 
100
          a new GType named MamanBaz which inherits from <span class="type"><a href="gobject-The-Base-Object-Type.html#GObject">GObject</a></span> and which
 
101
          implements the interface <span class="type">MamanIBaz</span>.
 
102
</p>
 
103
<pre class="programlisting">
 
104
static void maman_baz_do_action (MamanIbaz *self)
 
105
{
 
106
  g_print ("Baz implementation of IBaz interface Action.\n");
 
107
}
 
108
 
 
109
 
 
110
static void
 
111
baz_interface_init (gpointer         g_iface,
 
112
                    gpointer         iface_data)
 
113
{
 
114
  MamanIbazInterface *iface = (MamanIbazInterface *)g_iface;
 
115
  iface-&gt;do_action = maman_baz_do_action;
 
116
}
 
117
 
 
118
GType 
 
119
maman_baz_get_type (void)
 
120
{
 
121
  static GType type = 0;
 
122
  if (type == 0) {
 
123
    static const GTypeInfo info = {
 
124
      sizeof (MamanBazInterface),
 
125
      NULL,   /* base_init */
 
126
      NULL,   /* base_finalize */
 
127
      NULL,   /* class_init */
 
128
      NULL,   /* class_finalize */
 
129
      NULL,   /* class_data */
 
130
      sizeof (MamanBaz),
 
131
      0,      /* n_preallocs */
 
132
      NULL    /* instance_init */
 
133
    };
 
134
    static const GInterfaceInfo ibaz_info = {
 
135
      (GInterfaceInitFunc) baz_interface_init,    /* interface_init */
 
136
      NULL,               /* interface_finalize */
 
137
      NULL          /* interface_data */
 
138
    };
 
139
    type = g_type_register_static (G_TYPE_OBJECT,
 
140
                                   "MamanBazType",
 
141
                                   &amp;info, 0);
 
142
    g_type_add_interface_static (type,
 
143
                                 MAMAN_IBAZ_TYPE,
 
144
                                 &amp;ibaz_info);
 
145
  }
 
146
  return type;
 
147
}
 
148
</pre>
 
149
<p>
 
150
        </p>
 
151
<p>
 
152
          <code class="function"><a href="gobject-Type-Information.html#g-type-add-interface-static">g_type_add_interface_static</a></code> records in the type system that
 
153
          a given type implements also <span class="type">FooInterface</span> 
 
154
          (<code class="function">foo_interface_get_type</code> returns the type of 
 
155
          <span class="type">FooInterface</span>).
 
156
                The <span class="type"><a href="gobject-Type-Information.html#GInterfaceInfo">GInterfaceInfo</a></span> structure holds
 
157
          information about the implementation of the interface:
 
158
</p>
 
159
<pre class="programlisting">
 
160
struct _GInterfaceInfo
 
161
{
 
162
  GInterfaceInitFunc     interface_init;
 
163
  GInterfaceFinalizeFunc interface_finalize;
 
164
  gpointer               interface_data;
 
165
};
 
166
</pre>
 
167
<p>
 
168
        </p>
 
169
<div class="sect2" lang="en">
 
170
<div class="titlepage"><div><div><h3 class="title">
 
171
<a name="gtype-non-instantiable-classed-init"></a>Interface Initialization</h3></div></div></div>
 
172
<p>
 
173
            When an instantiable classed type which registered an interface implementation
 
174
            is created for the first time, its class structure is initialized following the process
 
175
            described in <a href="gtype-instantiable-classed.html" title="Instantiable classed types: objects">the section called &#8220;Instantiable classed types: objects&#8221;</a>. Once the class structure is 
 
176
              initialized,the function <code class="function">type_class_init_Wm</code> (implemented in <code class="filename">
 
177
              gtype.c</code>) initializes the interface implementations associated with
 
178
              that type by calling <code class="function">type_iface_vtable_init_Wm</code> for each
 
179
              interface.
 
180
          </p>
 
181
<p>
 
182
            First a memory buffer is allocated to hold the interface structure. The parent's
 
183
            interface structure is then copied over to the new interface structure (the parent
 
184
            interface is already initialized at that point). If there is no parent interface,
 
185
            the interface structure is initialized with zeros. The g_type and the g_instance_type
 
186
            fields are then initialized: g_type is set to the type of the most-derived interface
 
187
            and g_instance_type is set to the type of the most derived type which implements 
 
188
            this interface.
 
189
          </p>
 
190
<p>
 
191
            Finally, the interface' most-derived <code class="function">base_init</code> function and then 
 
192
            the implementation's <code class="function">interface_init</code>
 
193
            function are invoked. It is important to understand that if there are multiple 
 
194
            implementations of an interface the <code class="function">base_init</code> and 
 
195
            <code class="function">interface_init</code> functions will be
 
196
            invoked once for each implementation initialized.
 
197
          </p>
 
198
<p>
 
199
            It is thus common for base_init functions to hold a local static boolean variable
 
200
            which makes sure that the interface type is initialized only once even if there are 
 
201
            multiple implementations of the interface:
 
202
</p>
 
203
<pre class="programlisting">
 
204
static void
 
205
maman_ibaz_base_init (gpointer g_iface)
 
206
{
 
207
  static gboolean initialized = FALSE;
 
208
 
 
209
  if (!initialized) {
 
210
    /* create interface signals here. */
 
211
    initialized = TRUE;
 
212
  }
 
213
}
 
214
</pre>
 
215
<p>
 
216
          </p>
 
217
<p>
 
218
          If you have found the stuff about interface hairy, you are right: it is hairy but
 
219
          there is not much I can do about it. What I can do is summarize what you need to know
 
220
          about interfaces:       
 
221
        </p>
 
222
<p>
 
223
            The above process can be summarized as follows:
 
224
          </p>
 
225
<div class="table">
 
226
<a name="id3013724"></a><p class="title"><b>Table&#160;2.&#160;Interface Initialization</b></p>
 
227
<div class="table-contents"><table summary="Interface Initialization" border="1">
 
228
<colgroup>
 
229
<col align="left">
 
230
<col align="left">
 
231
<col align="left">
 
232
</colgroup>
 
233
<thead><tr>
 
234
<th align="left">Invocation time</th>
 
235
<th align="left">Function Invoked</th>
 
236
<th align="left">Function's parameters</th>
 
237
<th>Remark</th>
 
238
</tr></thead>
 
239
<tbody>
 
240
<tr>
 
241
<td align="left">First call to <code class="function"><a href="gobject-Type-Information.html#g-type-create-instance">g_type_create_instance</a></code> for type
 
242
                    implementing interface</td>
 
243
<td align="left">interface' base_init function</td>
 
244
<td align="left">On interface' vtable</td>
 
245
<td>Register interface' signals here (use a local static 
 
246
                    boolean variable as described above to make sure not to register them
 
247
                    twice.).</td>
 
248
</tr>
 
249
<tr>
 
250
<td align="left">First call to <code class="function"><a href="gobject-Type-Information.html#g-type-create-instance">g_type_create_instance</a></code> for type
 
251
                    implementing interface</td>
 
252
<td align="left">interface' interface_init function</td>
 
253
<td align="left">On interface' vtable</td>
 
254
<td>
 
255
                    Initialize interface' implementation. That is, initialize the interface 
 
256
                    method pointers in the interface structure to the function's implementation.
 
257
                  </td>
 
258
</tr>
 
259
</tbody>
 
260
</table></div>
 
261
</div>
 
262
<p><br class="table-break">
 
263
          It is highly unlikely (ie: I do not know of <span class="emphasis"><em>anyone</em></span> who actually 
 
264
          used it) you will ever need other more fancy things such as the ones described in the
 
265
          following section (<a href="gtype-non-instantiable-classed.html#gtype-non-instantiable-classed-dest" title="Interface Destruction">the section called &#8220;Interface Destruction&#8221;</a>).
 
266
        </p>
 
267
</div>
 
268
<div class="sect2" lang="en">
 
269
<div class="titlepage"><div><div><h3 class="title">
 
270
<a name="gtype-non-instantiable-classed-dest"></a>Interface Destruction</h3></div></div></div>
 
271
<p>
 
272
            When the last instance of an instantiable type which registered an interface implementation
 
273
            is destroyed, the interface's implementations associated to the type are destroyed by
 
274
            <code class="function">type_iface_vtable_finalize_Wm</code> (in <code class="filename">gtype.c</code>).
 
275
          </p>
 
276
<p>
 
277
            <code class="function">type_iface_vtable_finalize_Wm</code> invokes first the implementation's 
 
278
            <code class="function">interface_finalize</code> function and then the interface's most-derived
 
279
            <code class="function">base_finalize</code> function.
 
280
          </p>
 
281
<p>
 
282
            Again, it is important to understand, as in 
 
283
            <a href="gtype-non-instantiable-classed.html#gtype-non-instantiable-classed-init" title="Interface Initialization">the section called &#8220;Interface Initialization&#8221;</a>,
 
284
              that both <code class="function">interface_finalize</code> and <code class="function">base_finalize</code>
 
285
              are invoked exactly once for the destruction of each implementation of an interface. Thus,
 
286
              if you were to use one of these functions, you would need to use a static integer variable
 
287
              which would hold the number of instances of implementations of an interface such that
 
288
              the interface's class is destroyed only once (when the integer variable reaches zero).
 
289
          </p>
 
290
<p>
 
291
            The above process can be summarized as follows:
 
292
          </p>
 
293
<div class="table">
 
294
<a name="id3013950"></a><p class="title"><b>Table&#160;3.&#160;Interface Finalization</b></p>
 
295
<div class="table-contents"><table summary="Interface Finalization" border="1">
 
296
<colgroup>
 
297
<col align="left">
 
298
<col align="left">
 
299
<col align="left">
 
300
</colgroup>
 
301
<thead><tr>
 
302
<th align="left">Invocation time</th>
 
303
<th align="left">Function Invoked</th>
 
304
<th align="left">Function's parameters</th>
 
305
</tr></thead>
 
306
<tbody>
 
307
<tr>
 
308
<td align="left">Last call to <code class="function"><a href="gobject-Type-Information.html#g-type-free-instance">g_type_free_instance</a></code> for type
 
309
                    implementing interface</td>
 
310
<td align="left">interface' interface_finalize function</td>
 
311
<td align="left">On interface' vtable</td>
 
312
</tr>
 
313
<tr>
 
314
<td align="left">Last call to <code class="function"><a href="gobject-Type-Information.html#g-type-free-instance">g_type_free_instance</a></code>for type
 
315
                    implementing interface</td>
 
316
<td align="left">interface' base_finalize function</td>
 
317
<td align="left">On interface' vtable</td>
 
318
</tr>
 
319
</tbody>
 
320
</table></div>
 
321
</div>
 
322
<p><br class="table-break">
 
323
        </p>
 
324
<p>
 
325
          Now that you have read this section, you can forget about it. Please, forget it
 
326
          <span class="emphasis"><em>as soon as possible</em></span>.
 
327
        </p>
 
328
</div>
 
329
</div>
 
330
</body>
 
331
</html>