mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-09 18:54:04 +02:00
docs: syntax highlighting for the code examples
In the sections Concepts, Tools and Tutorial. https://bugzilla.gnome.org/show_bug.cgi?id=736914
This commit is contained in:
@@ -51,9 +51,9 @@ passed as additional arguments on the command line.
|
|||||||
<para>
|
<para>
|
||||||
The marshaller lists are processed line by line, a line can contain a
|
The marshaller lists are processed line by line, a line can contain a
|
||||||
comment in the form of
|
comment in the form of
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
# this is a comment
|
# this is a comment
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
or a marshaller specification of the form
|
or a marshaller specification of the form
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<replaceable>RTYPE</replaceable>:<replaceable>PTYPE</replaceable>
|
<replaceable>RTYPE</replaceable>:<replaceable>PTYPE</replaceable>
|
||||||
@@ -329,7 +329,7 @@ Print version and exit.
|
|||||||
<para>
|
<para>
|
||||||
To generate marshallers for the following callback functions:
|
To generate marshallers for the following callback functions:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void foo (gpointer data1,
|
void foo (gpointer data1,
|
||||||
gpointer data2);
|
gpointer data2);
|
||||||
void bar (gpointer data1,
|
void bar (gpointer data1,
|
||||||
@@ -339,7 +339,7 @@ gfloat baz (gpointer data1,
|
|||||||
gboolean param1,
|
gboolean param1,
|
||||||
guchar param2,
|
guchar param2,
|
||||||
gpointer data2);
|
gpointer data2);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<para>
|
<para>
|
||||||
The <filename>marshaller.list</filename> file has to look like this:
|
The <filename>marshaller.list</filename> file has to look like this:
|
||||||
</para>
|
</para>
|
||||||
@@ -368,7 +368,7 @@ g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR().
|
|||||||
They can be used directly for GClosures or be passed in as the
|
They can be used directly for GClosures or be passed in as the
|
||||||
GSignalCMarshaller c_marshaller; argument upon creation of signals:
|
GSignalCMarshaller c_marshaller; argument upon creation of signals:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GClosure *cc_foo, *cc_bar, *cc_baz;
|
GClosure *cc_foo, *cc_bar, *cc_baz;
|
||||||
|
|
||||||
cc_foo = g_cclosure_new (NULL, foo, NULL);
|
cc_foo = g_cclosure_new (NULL, foo, NULL);
|
||||||
@@ -377,7 +377,7 @@ cc_bar = g_cclosure_new (NULL, bar, NULL);
|
|||||||
g_closure_set_marshal (cc_bar, g_cclosure_user_marshal_VOID__INT);
|
g_closure_set_marshal (cc_bar, g_cclosure_user_marshal_VOID__INT);
|
||||||
cc_baz = g_cclosure_new (NULL, baz, NULL);
|
cc_baz = g_cclosure_new (NULL, baz, NULL);
|
||||||
g_closure_set_marshal (cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
|
g_closure_set_marshal (cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
<refsect1><title>See also</title>
|
<refsect1><title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
|
@@ -50,13 +50,13 @@ in @ characters.
|
|||||||
Certain keywords enclosed in @ characters will be substituted in the
|
Certain keywords enclosed in @ characters will be substituted in the
|
||||||
emitted text. For the substitution examples of the keywords below,
|
emitted text. For the substitution examples of the keywords below,
|
||||||
the following example enum definition is assumed:
|
the following example enum definition is assumed:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PREFIX_THE_XVALUE = 1 << 3,
|
PREFIX_THE_XVALUE = 1 << 3,
|
||||||
PREFIX_ANOTHER_VALUE = 1 << 4
|
PREFIX_ANOTHER_VALUE = 1 << 4
|
||||||
} PrefixTheXEnum;
|
} PrefixTheXEnum;
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>@EnumName@</term>
|
<term>@EnumName@</term>
|
||||||
@@ -185,7 +185,7 @@ Per value definition, the options "skip" and "nick" are supported.
|
|||||||
The former causes the value to be skipped, and the latter can be used to
|
The former causes the value to be skipped, and the latter can be used to
|
||||||
specify the otherwise auto-generated nickname.
|
specify the otherwise auto-generated nickname.
|
||||||
Examples:
|
Examples:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
typedef enum /*< skip >*/
|
typedef enum /*< skip >*/
|
||||||
{
|
{
|
||||||
PREFIX_FOO
|
PREFIX_FOO
|
||||||
@@ -197,7 +197,7 @@ typedef enum /*< flags,prefix=PREFIX >*/
|
|||||||
PREFIX_THE_SECOND_VALUE,
|
PREFIX_THE_SECOND_VALUE,
|
||||||
PREFIX_THE_THIRD_VALUE, /*< nick=the-last-value >*/
|
PREFIX_THE_THIRD_VALUE, /*< nick=the-last-value >*/
|
||||||
} PrefixTheFlagsEnum;
|
} PrefixTheFlagsEnum;
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@@ -272,10 +272,10 @@ Template for auto-generated comments, the default (for C code generations) is
|
|||||||
<listitem><para>
|
<listitem><para>
|
||||||
Read templates from the given file. The templates are enclosed in
|
Read templates from the given file. The templates are enclosed in
|
||||||
specially-formatted C comments
|
specially-formatted C comments
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/*** BEGIN section ***/
|
/*** BEGIN section ***/
|
||||||
/*** END section ***/
|
/*** END section ***/
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
where section may be <literal>file-header</literal>,
|
where section may be <literal>file-header</literal>,
|
||||||
<literal>file-production</literal>, <literal>file-tail</literal>,
|
<literal>file-production</literal>, <literal>file-tail</literal>,
|
||||||
<literal>enumeration-production</literal>, <literal>value-header</literal>,
|
<literal>enumeration-production</literal>, <literal>value-header</literal>,
|
||||||
|
@@ -51,16 +51,16 @@
|
|||||||
Objects which inherit from GObject are allowed to override this
|
Objects which inherit from GObject are allowed to override this
|
||||||
constructor class method: they should however chain to their parent
|
constructor class method: they should however chain to their parent
|
||||||
constructor method before doing so:
|
constructor method before doing so:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GObject *(* constructor) (GType gtype,
|
GObject *(* constructor) (GType gtype,
|
||||||
guint n_properties,
|
guint n_properties,
|
||||||
GObjectConstructParam *properties);
|
GObjectConstructParam *properties);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The example below shows how <type>MamanBar</type> overrides the parent's constructor:
|
The example below shows how <type>MamanBar</type> overrides the parent's constructor:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
|
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
|
||||||
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
|
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
|
||||||
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
|
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
|
||||||
@@ -119,11 +119,11 @@ maman_bar_init (MamanBar *self)
|
|||||||
/* initialize the object */
|
/* initialize the object */
|
||||||
}
|
}
|
||||||
|
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
If the user instantiates an object <type>MamanBar</type> with:
|
If the user instantiates an object <type>MamanBar</type> with:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
If this is the first instantiation of such an object, the
|
If this is the first instantiation of such an object, the
|
||||||
<function>maman_bar_class_init</function> function will be invoked
|
<function>maman_bar_class_init</function> function will be invoked
|
||||||
after any <function>maman_bar_base_class_init</function> function.
|
after any <function>maman_bar_base_class_init</function> function.
|
||||||
@@ -266,7 +266,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
|||||||
which can be integrated in applications which use or require different memory management
|
which can be integrated in applications which use or require different memory management
|
||||||
models (such as garbage collection). The methods which are used to
|
models (such as garbage collection). The methods which are used to
|
||||||
manipulate this reference count are described below.
|
manipulate this reference count are described below.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/*
|
/*
|
||||||
Refcounting
|
Refcounting
|
||||||
*/
|
*/
|
||||||
@@ -293,7 +293,7 @@ void g_object_remove_weak_pointer (GObject *object,
|
|||||||
* Cycle handling
|
* Cycle handling
|
||||||
*/
|
*/
|
||||||
void g_object_run_dispose (GObject *object);
|
void g_object_run_dispose (GObject *object);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2 id="gobject-memory-refcount">
|
<sect2 id="gobject-memory-refcount">
|
||||||
@@ -705,14 +705,14 @@ g_value_unset (&val);
|
|||||||
It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
|
It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
|
||||||
<function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (vararg version) functions can be used to set
|
<function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (vararg version) functions can be used to set
|
||||||
multiple properties at once. The client code shown above can then be re-written as:
|
multiple properties at once. The client code shown above can then be re-written as:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
MamanBar *foo;
|
MamanBar *foo;
|
||||||
foo = /* */;
|
foo = /* */;
|
||||||
g_object_set (G_OBJECT (foo),
|
g_object_set (G_OBJECT (foo),
|
||||||
"papa-number", 2,
|
"papa-number", 2,
|
||||||
"maman-name", "test",
|
"maman-name", "test",
|
||||||
NULL);
|
NULL);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
This saves us from managing the GValues that we were needing to handle when using
|
This saves us from managing the GValues that we were needing to handle when using
|
||||||
<function><link linkend="g-object-set-property">g_object_set_property</link></function>.
|
<function><link linkend="g-object-set-property">g_object_set_property</link></function>.
|
||||||
The code above will trigger one notify signal emission for each property modified.
|
The code above will trigger one notify signal emission for each property modified.
|
||||||
|
@@ -15,9 +15,9 @@
|
|||||||
which contains three objects:
|
which contains three objects:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>a function pointer (the callback itself) whose prototype looks like:
|
<listitem><para>a function pointer (the callback itself) whose prototype looks like:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
return_type function_callback (... , gpointer user_data);
|
return_type function_callback (... , gpointer user_data);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
the user_data pointer which is passed to the callback upon invocation of the closure
|
the user_data pointer which is passed to the callback upon invocation of the closure
|
||||||
@@ -80,7 +80,7 @@ return_type function_callback (... , gpointer user_data);
|
|||||||
to connect a callback to a given event, you will either use simple <link linkend="GCClosure"><type>GCClosure</type></link>s
|
to connect a callback to a given event, you will either use simple <link linkend="GCClosure"><type>GCClosure</type></link>s
|
||||||
which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function>
|
which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function>
|
||||||
functions (which will be presented a bit later :).
|
functions (which will be presented a bit later :).
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GClosure *g_cclosure_new (GCallback callback_func,
|
GClosure *g_cclosure_new (GCallback callback_func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GClosureNotify destroy_data);
|
GClosureNotify destroy_data);
|
||||||
@@ -89,7 +89,7 @@ GClosure *g_cclosure_new_swap (GCallback callback_func,
|
|||||||
GClosureNotify destroy_data);
|
GClosureNotify destroy_data);
|
||||||
GClosure *g_signal_type_cclosure_new (GType itype,
|
GClosure *g_signal_type_cclosure_new (GType itype,
|
||||||
guint struct_offset);
|
guint struct_offset);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -128,7 +128,7 @@ GClosure *g_signal_type_cclosure_new (GType itype,
|
|||||||
<para>
|
<para>
|
||||||
The following code implements a simple marshaller in C for a C function which takes an
|
The following code implements a simple marshaller in C for a C function which takes an
|
||||||
integer as first parameter and returns void.
|
integer as first parameter and returns void.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
g_cclosure_marshal_VOID__INT (GClosure *closure,
|
g_cclosure_marshal_VOID__INT (GClosure *closure,
|
||||||
GValue *return_value,
|
GValue *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
@@ -154,7 +154,7 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
|
|||||||
g_marshal_value_peek_int (param_values + 1),
|
g_marshal_value_peek_int (param_values + 1),
|
||||||
data2);
|
data2);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -194,9 +194,9 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
|
|||||||
When a signal is emitted on a given type instance, all the closures
|
When a signal is emitted on a given type instance, all the closures
|
||||||
connected to this signal on this type instance will be invoked. All the closures
|
connected to this signal on this type instance will be invoked. All the closures
|
||||||
connected to such a signal represent callbacks whose signature looks like:
|
connected to such a signal represent callbacks whose signature looks like:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
return_type function_callback (gpointer instance, ... , gpointer user_data);
|
return_type function_callback (gpointer instance, ... , gpointer user_data);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2 id="signal-registration">
|
<sect2 id="signal-registration">
|
||||||
@@ -205,7 +205,7 @@ return_type function_callback (gpointer instance, ... , gpointer user_data);
|
|||||||
<para>
|
<para>
|
||||||
To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
|
To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
|
||||||
<function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
|
<function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
guint g_signal_newv (const gchar *signal_name,
|
guint g_signal_newv (const gchar *signal_name,
|
||||||
GType itype,
|
GType itype,
|
||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
@@ -216,7 +216,7 @@ guint g_signal_newv (const gchar *signal_name,
|
|||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
GType *param_types);
|
GType *param_types);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The number of parameters to these functions is a bit intimidating but they are relatively
|
The number of parameters to these functions is a bit intimidating but they are relatively
|
||||||
simple:
|
simple:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
@@ -310,12 +310,12 @@ guint g_signal_newv (const gchar *signal_name,
|
|||||||
<para>
|
<para>
|
||||||
Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
|
Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
|
||||||
of functions.
|
of functions.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void g_signal_emitv (const GValue *instance_and_params,
|
void g_signal_emitv (const GValue *instance_and_params,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
GValue *return_value);
|
GValue *return_value);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
The instance_and_params array of GValues contains the list of input
|
The instance_and_params array of GValues contains the list of input
|
||||||
@@ -440,15 +440,15 @@ void g_signal_emitv (const GValue *instance_and_params,
|
|||||||
<function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
|
<function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
|
||||||
</para>
|
</para>
|
||||||
</footnote>:
|
</footnote>:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
gulong g_signal_connect_closure_by_id (gpointer instance,
|
gulong g_signal_connect_closure_by_id (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gboolean after);
|
gboolean after);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The two other functions hide the detail parameter in the signal name identification:
|
The two other functions hide the detail parameter in the signal name identification:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
gulong g_signal_connect_closure (gpointer instance,
|
gulong g_signal_connect_closure (gpointer instance,
|
||||||
const gchar *detailed_signal,
|
const gchar *detailed_signal,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
@@ -459,7 +459,7 @@ gulong g_signal_connect_data (gpointer instance,
|
|||||||
gpointer data,
|
gpointer data,
|
||||||
GClosureNotify destroy_data,
|
GClosureNotify destroy_data,
|
||||||
GConnectFlags connect_flags);
|
GConnectFlags connect_flags);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
Their detailed_signal parameter is a string which identifies the name of the signal
|
Their detailed_signal parameter is a string which identifies the name of the signal
|
||||||
to connect to. However, the format of this string is structured to look like
|
to connect to. However, the format of this string is structured to look like
|
||||||
<emphasis>signal_name::detail_name</emphasis>. Connecting to the signal
|
<emphasis>signal_name::detail_name</emphasis>. Connecting to the signal
|
||||||
@@ -471,7 +471,7 @@ gulong g_signal_connect_data (gpointer instance,
|
|||||||
<para>
|
<para>
|
||||||
Of the four main signal emission functions, three have an explicit detail parameter as a
|
Of the four main signal emission functions, three have an explicit detail parameter as a
|
||||||
<link linkend="GQuark"><type>GQuark</type></link> again:
|
<link linkend="GQuark"><type>GQuark</type></link> again:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void g_signal_emitv (const GValue *instance_and_params,
|
void g_signal_emitv (const GValue *instance_and_params,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
@@ -484,13 +484,13 @@ void g_signal_emit (gpointer instance,
|
|||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
...);
|
...);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The fourth function hides it in its signal name parameter:
|
The fourth function hides it in its signal name parameter:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void g_signal_emit_by_name (gpointer instance,
|
void g_signal_emit_by_name (gpointer instance,
|
||||||
const gchar *detailed_signal,
|
const gchar *detailed_signal,
|
||||||
...);
|
...);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The format of the detailed_signal parameter is exactly the same as the format used by
|
The format of the detailed_signal parameter is exactly the same as the format used by
|
||||||
the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
|
the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
|
||||||
</para>
|
</para>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
A type, as manipulated by the GLib type system, is much more generic than what
|
A type, as manipulated by the GLib type system, is much more generic than what
|
||||||
is usually understood as an Object type. It is best explained by looking at the
|
is usually understood as an Object type. It is best explained by looking at the
|
||||||
structure and the functions used to register new types in the type system.
|
structure and the functions used to register new types in the type system.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
typedef struct _GTypeInfo GTypeInfo;
|
typedef struct _GTypeInfo GTypeInfo;
|
||||||
struct _GTypeInfo
|
struct _GTypeInfo
|
||||||
{
|
{
|
||||||
@@ -41,7 +41,7 @@ GType g_type_register_fundamental (GType type_id,
|
|||||||
const GTypeInfo *info,
|
const GTypeInfo *info,
|
||||||
const GTypeFundamentalInfo *finfo,
|
const GTypeFundamentalInfo *finfo,
|
||||||
GTypeFlags flags);
|
GTypeFlags flags);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -133,7 +133,7 @@ GType g_type_register_fundamental (GType type_id,
|
|||||||
The following code shows how you can copy around a 64 bit integer, as well as a <link linkend="GObject"><type>GObject</type></link>
|
The following code shows how you can copy around a 64 bit integer, as well as a <link linkend="GObject"><type>GObject</type></link>
|
||||||
instance pointer (sample code for this is located in the source tarball for this document in
|
instance pointer (sample code for this is located in the source tarball for this document in
|
||||||
<filename>sample/gtype/test.c</filename>):
|
<filename>sample/gtype/test.c</filename>):
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void test_int (void)
|
static void test_int (void)
|
||||||
{
|
{
|
||||||
GValue a_value = G_VALUE_INIT;
|
GValue a_value = G_VALUE_INIT;
|
||||||
@@ -179,7 +179,7 @@ static void test_object (void)
|
|||||||
g_object_unref (G_OBJECT (obj));
|
g_object_unref (G_OBJECT (obj));
|
||||||
g_object_unref (G_OBJECT (obj));
|
g_object_unref (G_OBJECT (obj));
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The important point about the above code is that the exact semantics of the copy calls
|
The important point about the above code is that the exact semantics of the copy calls
|
||||||
is undefined since they depend on the implementation of the copy function. Certain
|
is undefined since they depend on the implementation of the copy function. Certain
|
||||||
copy functions might decide to allocate a new chunk of memory and then to copy the
|
copy functions might decide to allocate a new chunk of memory and then to copy the
|
||||||
@@ -192,7 +192,7 @@ static void test_object (void)
|
|||||||
<filename>gtype.h</filename> and is thoroughly described in the
|
<filename>gtype.h</filename> and is thoroughly described in the
|
||||||
API documentation provided with GObject (for once ;-) which is why we will
|
API documentation provided with GObject (for once ;-) which is why we will
|
||||||
not detail its exact semantics.
|
not detail its exact semantics.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
typedef struct _GTypeValueTable GTypeValueTable;
|
typedef struct _GTypeValueTable GTypeValueTable;
|
||||||
struct _GTypeValueTable
|
struct _GTypeValueTable
|
||||||
{
|
{
|
||||||
@@ -213,7 +213,7 @@ struct _GTypeValueTable
|
|||||||
GTypeCValue *collect_values,
|
GTypeCValue *collect_values,
|
||||||
guint collect_flags);
|
guint collect_flags);
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
Interestingly, it is also very unlikely
|
Interestingly, it is also very unlikely
|
||||||
you will ever need to specify a value_table during type registration
|
you will ever need to specify a value_table during type registration
|
||||||
because these value_tables are inherited from the parent types for
|
because these value_tables are inherited from the parent types for
|
||||||
@@ -290,21 +290,21 @@ struct _GTypeValueTable
|
|||||||
The implementation of these macros is pretty straightforward: a number of simple-to-use
|
The implementation of these macros is pretty straightforward: a number of simple-to-use
|
||||||
macros are provided in <filename>gtype.h</filename>. For the example we used above, we would
|
macros are provided in <filename>gtype.h</filename>. For the example we used above, we would
|
||||||
write the following trivial code to declare the macros:
|
write the following trivial code to declare the macros:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
|
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
|
||||||
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
|
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
|
||||||
#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
|
#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
|
||||||
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
|
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
|
||||||
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
|
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
|
||||||
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
|
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<note><simpara>Stick to the naming <varname>klass</varname> as <varname>class</varname> is a registered c++ keyword.</simpara></note>
|
<note><simpara>Stick to the naming <varname>klass</varname> as <varname>class</varname> is a registered c++ keyword.</simpara></note>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The following code shows how to implement the <function>maman_bar_get_type</function>
|
The following code shows how to implement the <function>maman_bar_get_type</function>
|
||||||
function:
|
function:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GType maman_bar_get_type (void)
|
GType maman_bar_get_type (void)
|
||||||
{
|
{
|
||||||
static GType type = 0;
|
static GType type = 0;
|
||||||
@@ -318,16 +318,16 @@ GType maman_bar_get_type (void)
|
|||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If you have no special requirements you can use the
|
If you have no special requirements you can use the
|
||||||
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
|
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
|
||||||
macro to define a class:
|
macro to define a class:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
@@ -345,7 +345,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
|||||||
To register such a type in the type system, you just need to fill the
|
To register such a type in the type system, you just need to fill the
|
||||||
<link linkend="GTypeInfo"><type>GTypeInfo</type></link> structure with zeros since these types are also most of the time
|
<link linkend="GTypeInfo"><type>GTypeInfo</type></link> structure with zeros since these types are also most of the time
|
||||||
fundamental:
|
fundamental:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GTypeInfo info = {
|
GTypeInfo info = {
|
||||||
0, /* class_size */
|
0, /* class_size */
|
||||||
NULL, /* base_init */
|
NULL, /* base_init */
|
||||||
@@ -370,7 +370,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
|||||||
};
|
};
|
||||||
info.value_table = &value_table;
|
info.value_table = &value_table;
|
||||||
type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo, 0);
|
type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo, 0);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
|||||||
<para>
|
<para>
|
||||||
For example, the code below shows how you could register
|
For example, the code below shows how you could register
|
||||||
such a fundamental object type in the type system:
|
such a fundamental object type in the type system:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
/* instance members */
|
/* instance members */
|
||||||
@@ -440,7 +440,7 @@ maman_bar_get_type (void)
|
|||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
Upon the first call to <function>maman_bar_get_type</function>, the type named
|
Upon the first call to <function>maman_bar_get_type</function>, the type named
|
||||||
<emphasis>BarType</emphasis> will be registered in the type system as inheriting
|
<emphasis>BarType</emphasis> will be registered in the type system as inheriting
|
||||||
from the type <emphasis>G_TYPE_OBJECT</emphasis>.
|
from the type <emphasis>G_TYPE_OBJECT</emphasis>.
|
||||||
@@ -452,7 +452,7 @@ maman_bar_get_type (void)
|
|||||||
a <link linkend="GTypeClass"><type>GTypeClass</type></link> structure. All instance structures must contain as first
|
a <link linkend="GTypeClass"><type>GTypeClass</type></link> structure. All instance structures must contain as first
|
||||||
member a <link linkend="GTypeInstance"><type>GTypeInstance</type></link> structure. The declaration of these C types,
|
member a <link linkend="GTypeInstance"><type>GTypeInstance</type></link> structure. The declaration of these C types,
|
||||||
coming from <filename>gtype.h</filename> is shown below:
|
coming from <filename>gtype.h</filename> is shown below:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
struct _GTypeClass
|
struct _GTypeClass
|
||||||
{
|
{
|
||||||
GType g_type;
|
GType g_type;
|
||||||
@@ -461,7 +461,7 @@ struct _GTypeInstance
|
|||||||
{
|
{
|
||||||
GTypeClass *g_class;
|
GTypeClass *g_class;
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
These constraints allow the type system to make sure that every object instance
|
These constraints allow the type system to make sure that every object instance
|
||||||
(identified by a pointer to the object's instance structure) contains in its
|
(identified by a pointer to the object's instance structure) contains in its
|
||||||
first bytes a pointer to the object's class structure.
|
first bytes a pointer to the object's class structure.
|
||||||
@@ -469,7 +469,7 @@ struct _GTypeInstance
|
|||||||
<para>
|
<para>
|
||||||
This relationship is best explained by an example: let's take object B which
|
This relationship is best explained by an example: let's take object B which
|
||||||
inherits from object A:
|
inherits from object A:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/* A definitions */
|
/* A definitions */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GTypeInstance parent;
|
GTypeInstance parent;
|
||||||
@@ -493,7 +493,7 @@ typedef struct {
|
|||||||
void (*method_c) (void);
|
void (*method_c) (void);
|
||||||
void (*method_d) (void);
|
void (*method_d) (void);
|
||||||
} BClass;
|
} BClass;
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The C standard mandates that the first field of a C structure is stored starting
|
The C standard mandates that the first field of a C structure is stored starting
|
||||||
in the first byte of the buffer used to hold the structure's fields in memory.
|
in the first byte of the buffer used to hold the structure's fields in memory.
|
||||||
This means that the first field of an instance of an object B is A's first field
|
This means that the first field of an instance of an object B is A's first field
|
||||||
@@ -504,15 +504,15 @@ typedef struct {
|
|||||||
<para>
|
<para>
|
||||||
Thanks to these simple conditions, it is possible to detect the type of every
|
Thanks to these simple conditions, it is possible to detect the type of every
|
||||||
object instance by doing:
|
object instance by doing:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
B *b;
|
B *b;
|
||||||
b->parent.parent.g_class->g_type
|
b->parent.parent.g_class->g_type
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
or, more quickly:
|
or, more quickly:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
B *b;
|
B *b;
|
||||||
((GTypeInstance*)b)->g_class->g_type
|
((GTypeInstance*)b)->g_class->g_type
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2 id="gtype-instantiable-classed-init-done">
|
<sect2 id="gtype-instantiable-classed-init-done">
|
||||||
@@ -521,10 +521,10 @@ B *b;
|
|||||||
<para>
|
<para>
|
||||||
instantiation of these types can be done with
|
instantiation of these types can be done with
|
||||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
|
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GTypeInstance* g_type_create_instance (GType type);
|
GTypeInstance* g_type_create_instance (GType type);
|
||||||
void g_type_free_instance (GTypeInstance *instance);
|
void g_type_free_instance (GTypeInstance *instance);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will look up the type information
|
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will look up the type information
|
||||||
structure associated to the type requested. Then, the instance size and instantiation
|
structure associated to the type requested. Then, the instance size and instantiation
|
||||||
policy (if the n_preallocs field is set to a non-zero value, the type system allocates
|
policy (if the n_preallocs field is set to a non-zero value, the type system allocates
|
||||||
@@ -662,7 +662,7 @@ void g_type_free_instance (GTypeInstance *instance);
|
|||||||
To declare an interface you have to register a non-instantiable
|
To declare an interface you have to register a non-instantiable
|
||||||
classed type which derives from
|
classed type which derives from
|
||||||
<link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
|
<link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
#define MAMAN_TYPE_IBAZ (maman_ibaz_get_type ())
|
#define MAMAN_TYPE_IBAZ (maman_ibaz_get_type ())
|
||||||
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
|
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
|
||||||
#define MAMAN_IS_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
|
#define MAMAN_IS_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
|
||||||
@@ -680,15 +680,15 @@ struct _MamanIbazInterface {
|
|||||||
GType maman_ibaz_get_type (void);
|
GType maman_ibaz_get_type (void);
|
||||||
|
|
||||||
void maman_ibaz_do_action (MamanIbaz *self);
|
void maman_ibaz_do_action (MamanIbaz *self);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The interface function, <function>maman_ibaz_do_action</function> is implemented
|
The interface function, <function>maman_ibaz_do_action</function> is implemented
|
||||||
in a pretty simple way:
|
in a pretty simple way:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void maman_ibaz_do_action (MamanIbaz *self)
|
void maman_ibaz_do_action (MamanIbaz *self)
|
||||||
{
|
{
|
||||||
MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
|
MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<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
|
which inherits from G_TYPE_INTERFACE. All interfaces must be children of G_TYPE_INTERFACE in the
|
||||||
inheritance tree.
|
inheritance tree.
|
||||||
@@ -708,7 +708,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
|
|||||||
interfaces. The function named <function>maman_baz_get_type</function> registers
|
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
|
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>
|
<informalexample><programlisting>
|
||||||
static void maman_baz_do_action (MamanIbaz *self)
|
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");
|
||||||
@@ -752,7 +752,7 @@ maman_baz_get_type (void)
|
|||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -762,21 +762,21 @@ maman_baz_get_type (void)
|
|||||||
<type>FooInterface</type>).
|
<type>FooInterface</type>).
|
||||||
The <link linkend="GInterfaceInfo"><type>GInterfaceInfo</type></link> structure holds
|
The <link linkend="GInterfaceInfo"><type>GInterfaceInfo</type></link> structure holds
|
||||||
information about the implementation of the interface:
|
information about the implementation of the interface:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
struct _GInterfaceInfo
|
struct _GInterfaceInfo
|
||||||
{
|
{
|
||||||
GInterfaceInitFunc interface_init;
|
GInterfaceInitFunc interface_init;
|
||||||
GInterfaceFinalizeFunc interface_finalize;
|
GInterfaceFinalizeFunc interface_finalize;
|
||||||
gpointer interface_data;
|
gpointer interface_data;
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If you have no special requirements you can use the
|
If you have no special requirements you can use the
|
||||||
<link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link> macro
|
<link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link> macro
|
||||||
to implement an interface:
|
to implement an interface:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_baz_do_action (MamanIbaz *self)
|
maman_baz_do_action (MamanIbaz *self)
|
||||||
{
|
{
|
||||||
@@ -792,7 +792,7 @@ maman_ibaz_interface_init (MamanIbazInterface *iface)
|
|||||||
G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
|
G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
|
||||||
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
||||||
maman_ibaz_interface_init));
|
maman_ibaz_interface_init));
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2 id="gtype-non-instantiable-classed-init">
|
<sect2 id="gtype-non-instantiable-classed-init">
|
||||||
@@ -835,7 +835,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
|
|||||||
<function>default_init</function> function is declared by
|
<function>default_init</function> function is declared by
|
||||||
<link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link>
|
<link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link>
|
||||||
which can be used to define the interface:
|
which can be used to define the interface:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);
|
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -843,12 +843,12 @@ maman_ibaz_default_init (MamanIbazInterface *iface)
|
|||||||
{
|
{
|
||||||
/* add properties and signals here, will only called once */
|
/* add properties and signals here, will only called once */
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Or you can do that yourself in a GType function for your interface:
|
Or you can do that yourself in a GType function for your interface:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GType
|
GType
|
||||||
maman_ibaz_get_type (void)
|
maman_ibaz_get_type (void)
|
||||||
{
|
{
|
||||||
@@ -878,7 +878,7 @@ maman_ibaz_default_init (MamanIbazInterface *iface)
|
|||||||
{
|
{
|
||||||
/* add properties and signals here, will only called once */
|
/* add properties and signals here, will only called once */
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@@ -88,7 +88,7 @@
|
|||||||
<function>MamanBar</function> and its class <function>MamanBarClass</function>
|
<function>MamanBar</function> and its class <function>MamanBarClass</function>
|
||||||
(name is case-sensitive). It is customary to declare them with code similar to the
|
(name is case-sensitive). It is customary to declare them with code similar to the
|
||||||
following:
|
following:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/*
|
/*
|
||||||
* Copyright/Licensing information.
|
* Copyright/Licensing information.
|
||||||
*/
|
*/
|
||||||
@@ -139,7 +139,7 @@ GType maman_bar_get_type (void);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* __MAMAN_BAR_H__ */
|
#endif /* __MAMAN_BAR_H__ */
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
Types that require per-instance private data should use the
|
Types that require per-instance private data should use the
|
||||||
@@ -150,7 +150,7 @@ GType maman_bar_get_type (void);
|
|||||||
function generated by the G_DEFINE_TYPE_* macros. It is automatically
|
function generated by the G_DEFINE_TYPE_* macros. It is automatically
|
||||||
zero-filled on creation, so it is unnecessary to explicitly
|
zero-filled on creation, so it is unnecessary to explicitly
|
||||||
initialize pointer members to NULL.
|
initialize pointer members to NULL.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
struct _MamanBarPrivate
|
struct _MamanBarPrivate
|
||||||
{
|
{
|
||||||
int hsize;
|
int hsize;
|
||||||
@@ -173,7 +173,7 @@ maman_bar_init (MamanBar *self)
|
|||||||
|
|
||||||
priv->hsize = 42;
|
priv->hsize = 42;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
@@ -183,7 +183,7 @@ maman_bar_init (MamanBar *self)
|
|||||||
and <ulink url="http://www.gotw.ca/gotw/028.htm">The Fast Pimpl Idiom</ulink>
|
and <ulink url="http://www.gotw.ca/gotw/028.htm">The Fast Pimpl Idiom</ulink>
|
||||||
for reference). If you opt to use this idiom, you can assign the
|
for reference). If you opt to use this idiom, you can assign the
|
||||||
pointer inside the instance initialization function, e.g.:
|
pointer inside the instance initialization function, e.g.:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||||
|
|
||||||
struct _MamanBarPrivate
|
struct _MamanBarPrivate
|
||||||
@@ -202,7 +202,7 @@ maman_bar_init (MamanBar *self)
|
|||||||
self->priv = maman_bar_get_instance_private (self);
|
self->priv = maman_bar_get_instance_private (self);
|
||||||
self->priv->hsize = 42;
|
self->priv->hsize = 42;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
@@ -238,7 +238,7 @@ maman_bar_init (MamanBar *self)
|
|||||||
on your header include strategy, this can be as simple as
|
on your header include strategy, this can be as simple as
|
||||||
<literal>#include "maman-bar.h"</literal> or as complicated as tens
|
<literal>#include "maman-bar.h"</literal> or as complicated as tens
|
||||||
of #include lines ending with <literal>#include "maman-bar.h"</literal>:
|
of #include lines ending with <literal>#include "maman-bar.h"</literal>:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/*
|
/*
|
||||||
* Copyright information
|
* Copyright information
|
||||||
*/
|
*/
|
||||||
@@ -258,7 +258,7 @@ struct _MamanBarPrivate {
|
|||||||
/*
|
/*
|
||||||
* forward definitions
|
* forward definitions
|
||||||
*/
|
*/
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -273,9 +273,9 @@ struct _MamanBarPrivate {
|
|||||||
the whole .c file</simpara></listitem>
|
the whole .c file</simpara></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -322,7 +322,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
As such, I would recommend writing the following code first:
|
As such, I would recommend writing the following code first:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -338,7 +338,7 @@ maman_bar_init (MamanBar *self)
|
|||||||
/* initialize all public and private members to reasonable default values.
|
/* initialize all public and private members to reasonable default values.
|
||||||
* They are all automatically initialized to 0 to begin with. */
|
* They are all automatically initialized to 0 to begin with. */
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -416,7 +416,7 @@ bar_class_init (MamanBarClass *klass)
|
|||||||
potential cycles due to the nature of the reference counting mechanism
|
potential cycles due to the nature of the reference counting mechanism
|
||||||
used by GObject, as well as dealing with temporary vivification of
|
used by GObject, as well as dealing with temporary vivification of
|
||||||
instances in case of signal emission during the destruction sequence.
|
instances in case of signal emission during the destruction sequence.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
struct _MamanBarPrivate
|
struct _MamanBarPrivate
|
||||||
{
|
{
|
||||||
GObject *an_object;
|
GObject *an_object;
|
||||||
@@ -480,7 +480,7 @@ maman_bar_init (MamanBar *self);
|
|||||||
self->priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL);
|
self->priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL);
|
||||||
self->priv->a_string = g_strdup ("Maman");
|
self->priv->a_string = g_strdup ("Maman");
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -522,7 +522,7 @@ maman_bar_init (MamanBar *self);
|
|||||||
can act on your object. All you need to do is to provide a function
|
can act on your object. All you need to do is to provide a function
|
||||||
prototype in the header and an implementation of that prototype
|
prototype in the header and an implementation of that prototype
|
||||||
in the source file.
|
in the source file.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/* declaration in the header. */
|
/* declaration in the header. */
|
||||||
void maman_bar_do_action (MamanBar *self, /* parameters */);
|
void maman_bar_do_action (MamanBar *self, /* parameters */);
|
||||||
|
|
||||||
@@ -534,7 +534,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
|||||||
|
|
||||||
/* do stuff here. */
|
/* do stuff here. */
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@@ -547,7 +547,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
|||||||
the public header, implement the common method in the source file
|
the public header, implement the common method in the source file
|
||||||
and re-implement the class function in each object which inherits
|
and re-implement the class function in each object which inherits
|
||||||
from you.
|
from you.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/* declaration in maman-bar.h. */
|
/* declaration in maman-bar.h. */
|
||||||
struct _MamanBarClass
|
struct _MamanBarClass
|
||||||
{
|
{
|
||||||
@@ -567,7 +567,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
|||||||
|
|
||||||
MAMAN_BAR_GET_CLASS (self)->do_action (self, /* parameters */);
|
MAMAN_BAR_GET_CLASS (self)->do_action (self, /* parameters */);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The code above simply redirects the do_action call to the relevant
|
The code above simply redirects the do_action call to the relevant
|
||||||
class function.
|
class function.
|
||||||
</para>
|
</para>
|
||||||
@@ -579,7 +579,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
|||||||
klass->do_action field to a pointer to the actual implementation.
|
klass->do_action field to a pointer to the actual implementation.
|
||||||
By default, class methods that are not inherited are initialized to
|
By default, class methods that are not inherited are initialized to
|
||||||
NULL, and thus are to be considered "pure virtual".
|
NULL, and thus are to be considered "pure virtual".
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_bar_real_do_action_two (MamanBar *self, /* parameters */)
|
maman_bar_real_do_action_two (MamanBar *self, /* parameters */)
|
||||||
{
|
{
|
||||||
@@ -624,7 +624,7 @@ maman_bar_do_action_two (MamanBar *self, /* parameters */)
|
|||||||
|
|
||||||
MAMAN_BAR_GET_CLASS (self)->do_action_two (self, /* parameters */);
|
MAMAN_BAR_GET_CLASS (self)->do_action_two (self, /* parameters */);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@@ -635,7 +635,7 @@ maman_bar_do_action_two (MamanBar *self, /* parameters */)
|
|||||||
These are very similar to Virtual Public methods. They just don't
|
These are very similar to Virtual Public methods. They just don't
|
||||||
have a public function to call the function directly. The header
|
have a public function to call the function directly. The header
|
||||||
file contains only a declaration of the class function:
|
file contains only a declaration of the class function:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/* declaration in maman-bar.h. */
|
/* declaration in maman-bar.h. */
|
||||||
struct _MamanBarClass
|
struct _MamanBarClass
|
||||||
{
|
{
|
||||||
@@ -646,10 +646,10 @@ struct _MamanBarClass
|
|||||||
};
|
};
|
||||||
|
|
||||||
void maman_bar_do_any_action (MamanBar *self, /* parameters */);
|
void maman_bar_do_any_action (MamanBar *self, /* parameters */);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
These class functions are often used to delegate part of the job
|
These class functions are often used to delegate part of the job
|
||||||
to child classes:
|
to child classes:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/* this accessor function is static: it is not exported outside of this file. */
|
/* this accessor function is static: it is not exported outside of this file. */
|
||||||
static void
|
static void
|
||||||
maman_bar_do_specific_action (MamanBar *self, /* parameters */)
|
maman_bar_do_specific_action (MamanBar *self, /* parameters */)
|
||||||
@@ -671,13 +671,13 @@ maman_bar_do_any_action (MamanBar *self, /* parameters */)
|
|||||||
|
|
||||||
/* other random code here */
|
/* other random code here */
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Again, it is possible to provide a default implementation for this
|
Again, it is possible to provide a default implementation for this
|
||||||
private virtual class function:
|
private virtual class function:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_bar_class_init (MamanBarClass *klass)
|
maman_bar_class_init (MamanBarClass *klass)
|
||||||
{
|
{
|
||||||
@@ -687,12 +687,12 @@ maman_bar_class_init (MamanBarClass *klass)
|
|||||||
/* merely virtual method. */
|
/* merely virtual method. */
|
||||||
klass->do_specific_action_two = maman_bar_real_do_specific_action_two;
|
klass->do_specific_action_two = maman_bar_real_do_specific_action_two;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Children can then implement the subclass with code such as:
|
Children can then implement the subclass with code such as:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
||||||
{
|
{
|
||||||
@@ -701,7 +701,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
|||||||
/* implement pure virtual class function. */
|
/* implement pure virtual class function. */
|
||||||
bar_class->do_specific_action_one = maman_bar_subtype_do_specific_action_one;
|
bar_class->do_specific_action_one = maman_bar_subtype_do_specific_action_one;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
@@ -754,7 +754,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
|||||||
directly, though, you should use the <function>parent_class</function>
|
directly, though, you should use the <function>parent_class</function>
|
||||||
pointer created and initialized for us by the G_DEFINE_TYPE_* family of
|
pointer created and initialized for us by the G_DEFINE_TYPE_* family of
|
||||||
macros, for instance:
|
macros, for instance:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
b_method_to_call (B *obj, int a)
|
b_method_to_call (B *obj, int a)
|
||||||
{
|
{
|
||||||
@@ -769,7 +769,7 @@ b_method_to_call (B *obj, int a)
|
|||||||
|
|
||||||
/* do stuff after chain up */
|
/* do stuff after chain up */
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
@@ -791,7 +791,7 @@ b_method_to_call (B *obj, int a)
|
|||||||
<para>
|
<para>
|
||||||
As above, the first step is to get the header right. This interface
|
As above, the first step is to get the header right. This interface
|
||||||
defines two methods:
|
defines two methods:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
#ifndef __MAMAN_IBAZ_H__
|
#ifndef __MAMAN_IBAZ_H__
|
||||||
#define __MAMAN_IBAZ_H__
|
#define __MAMAN_IBAZ_H__
|
||||||
|
|
||||||
@@ -820,7 +820,7 @@ void maman_ibaz_do_action (MamanIbaz *self);
|
|||||||
void maman_ibaz_do_something (MamanIbaz *self);
|
void maman_ibaz_do_something (MamanIbaz *self);
|
||||||
|
|
||||||
#endif /* __MAMAN_IBAZ_H__ */
|
#endif /* __MAMAN_IBAZ_H__ */
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
This code is the same as the code for a normal <link linkend="GType"><type>GType</type></link>
|
This code is the same as the code for a normal <link linkend="GType"><type>GType</type></link>
|
||||||
which derives from a <link linkend="GObject"><type>GObject</type></link> except for a few details:
|
which derives from a <link linkend="GObject"><type>GObject</type></link> except for a few details:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
@@ -859,7 +859,7 @@ void maman_ibaz_do_something (MamanIbaz *self);
|
|||||||
structure to access its associated interface function and call it.
|
structure to access its associated interface function and call it.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, 0);
|
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, 0);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -883,7 +883,7 @@ maman_ibaz_do_something (MamanIbaz *self)
|
|||||||
|
|
||||||
MAMAN_IBAZ_GET_INTERFACE (self)->do_something (self);
|
MAMAN_IBAZ_GET_INTERFACE (self)->do_something (self);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
@@ -896,7 +896,7 @@ maman_ibaz_do_something (MamanIbaz *self)
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The first step is to define a normal GObject class, like:
|
The first step is to define a normal GObject class, like:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
#ifndef __MAMAN_BAZ_H__
|
#ifndef __MAMAN_BAZ_H__
|
||||||
#define __MAMAN_BAZ_H__
|
#define __MAMAN_BAZ_H__
|
||||||
|
|
||||||
@@ -928,7 +928,7 @@ struct _MamanBazClass
|
|||||||
GType maman_baz_get_type (void);
|
GType maman_baz_get_type (void);
|
||||||
|
|
||||||
#endif /* __MAMAN_BAZ_H__ */
|
#endif /* __MAMAN_BAZ_H__ */
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<!-- Ha ha! "nothing weird or scary". I actually laughed out loud. Oh boy.
|
<!-- 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
|
The fact that we're so intimate with GObject that all this doesn't look
|
||||||
wierd, that's the scary thing. :) -->
|
wierd, that's the scary thing. :) -->
|
||||||
@@ -945,13 +945,13 @@ GType maman_baz_get_type (void);
|
|||||||
and the
|
and the
|
||||||
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
|
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
|
||||||
macros.
|
macros.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void maman_ibaz_interface_init (MamanIbazInterface *iface);
|
static void maman_ibaz_interface_init (MamanIbazInterface *iface);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
||||||
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
||||||
maman_ibaz_interface_init))
|
maman_ibaz_interface_init))
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
This definition is very much like all the similar functions we looked
|
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
|
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>.
|
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>.
|
||||||
@@ -967,7 +967,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
|||||||
<function>maman_baz_interface_init</function>, the interface
|
<function>maman_baz_interface_init</function>, the interface
|
||||||
initialization function: inside it every virtual method of the interface
|
initialization function: inside it every virtual method of the interface
|
||||||
must be assigned to its implementation:
|
must be assigned to its implementation:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_baz_do_action (MamanBaz *self)
|
maman_baz_do_action (MamanBaz *self)
|
||||||
{
|
{
|
||||||
@@ -995,7 +995,7 @@ maman_baz_init (MamanBaz *self)
|
|||||||
MamanBaz *self = MAMAN_BAZ (instance);
|
MamanBaz *self = MAMAN_BAZ (instance);
|
||||||
self->instance_member = 0xdeadbeaf;
|
self->instance_member = 0xdeadbeaf;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
@@ -1015,17 +1015,17 @@ maman_baz_init (MamanBaz *self)
|
|||||||
The mechanism described above is, in practice, very similar to
|
The mechanism described above is, in practice, very similar to
|
||||||
Java's interface I1 extends interface I2. The example below shows
|
Java's interface I1 extends interface I2. The example below shows
|
||||||
the GObject equivalent:
|
the GObject equivalent:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/* Make the MamanIbar interface require MamanIbaz interface. */
|
/* Make the MamanIbar interface require MamanIbaz interface. */
|
||||||
G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ);
|
G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
In the <function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
|
In the <function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
|
||||||
call above, the third parameter defines the prerequisite type. This
|
call above, the third parameter defines the prerequisite type. This
|
||||||
is the GType of either an interface or a class. In this case
|
is the GType of either an interface or a class. In this case
|
||||||
the MamanIbaz interface is a prerequisite of the MamanIbar. The code
|
the MamanIbaz interface is a prerequisite of the MamanIbar. The code
|
||||||
below shows how an implementation can implement both interfaces and
|
below shows how an implementation can implement both interfaces and
|
||||||
register their implementations:
|
register their implementations:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_ibar_do_another_action (MamanIbar *ibar)
|
maman_ibar_do_another_action (MamanIbar *ibar)
|
||||||
{
|
{
|
||||||
@@ -1083,7 +1083,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
|||||||
maman_ibaz_interface_init)
|
maman_ibaz_interface_init)
|
||||||
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAR,
|
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAR,
|
||||||
maman_ibar_interface_init))
|
maman_ibar_interface_init))
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
It is very important to notice that the order in which interface
|
It is very important to notice that the order in which interface
|
||||||
implementations are added to the main object is not random:
|
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>,
|
<function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function>,
|
||||||
@@ -1117,7 +1117,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
|||||||
</para>
|
</para>
|
||||||
</footnote>
|
</footnote>
|
||||||
line in the <function>maman_ibaz_default_init</function> as shown below:
|
line in the <function>maman_ibaz_default_init</function> as shown below:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_ibaz_default_init (MamanIbazInteface *iface)
|
maman_ibaz_default_init (MamanIbazInteface *iface)
|
||||||
{
|
{
|
||||||
@@ -1128,7 +1128,7 @@ maman_ibaz_default_init (MamanIbazInteface *iface)
|
|||||||
"maman",
|
"maman",
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -1147,7 +1147,7 @@ maman_ibaz_default_init (MamanIbazInteface *iface)
|
|||||||
instead of <function><link linkend="g-object-class-install-property">g_object_class_install_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
|
The following code snippet shows the modifications needed in the
|
||||||
<type>MamanBaz</type> declaration and implementation above:
|
<type>MamanBaz</type> declaration and implementation above:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
|
|
||||||
struct _MamanBaz
|
struct _MamanBaz
|
||||||
{
|
{
|
||||||
@@ -1215,7 +1215,7 @@ maman_baz_class_init (MamanBazClass *klass)
|
|||||||
g_object_class_override_property (gobject_class, PROP_NAME, "name");
|
g_object_class_override_property (gobject_class, PROP_NAME, "name");
|
||||||
}
|
}
|
||||||
|
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
@@ -1235,7 +1235,7 @@ maman_baz_class_init (MamanBazClass *klass)
|
|||||||
implement the MamanIbaz interface. MamanDerivedBaz only implements one
|
implement the MamanIbaz interface. MamanDerivedBaz only implements one
|
||||||
method of the MamanIbaz interface and uses the base class implementation
|
method of the MamanIbaz interface and uses the base class implementation
|
||||||
of the other.
|
of the other.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_derived_ibaz_do_action (MamanIbaz *ibaz)
|
maman_derived_ibaz_do_action (MamanIbaz *ibaz)
|
||||||
{
|
{
|
||||||
@@ -1270,7 +1270,7 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -1291,7 +1291,7 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
|||||||
In this example MamanDerivedBaz overides the
|
In this example MamanDerivedBaz overides the
|
||||||
<function>do_action</function> interface method. In its overridden method
|
<function>do_action</function> interface method. In its overridden method
|
||||||
it calls the base class implementation of the same interface method.
|
it calls the base class implementation of the same interface method.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static MamanIbazInterface *maman_ibaz_parent_interface = NULL;
|
static MamanIbazInterface *maman_ibaz_parent_interface = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1324,7 +1324,7 @@ static void
|
|||||||
maman_derived_baz_init (MamanDerivedBaz *self)
|
maman_derived_baz_init (MamanDerivedBaz *self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
@@ -1361,19 +1361,19 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
|||||||
whenever someone has changed something via our MamanFile instance.
|
whenever someone has changed something via our MamanFile instance.
|
||||||
The code below shows how the user can connect a callback to the
|
The code below shows how the user can connect a callback to the
|
||||||
"changed" signal.
|
"changed" signal.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
file = g_object_new (MAMAN_FILE_TYPE, NULL);
|
file = g_object_new (MAMAN_FILE_TYPE, NULL);
|
||||||
|
|
||||||
g_signal_connect (file, "changed", G_CALLBACK (changed_event), NULL);
|
g_signal_connect (file, "changed", G_CALLBACK (changed_event), NULL);
|
||||||
|
|
||||||
maman_file_write (file, buffer, strlen (buffer));
|
maman_file_write (file, buffer, strlen (buffer));
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <type>MamanFile</type> signal is registered in the class_init
|
The <type>MamanFile</type> signal is registered in the class_init
|
||||||
function:
|
function:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
file_signals[CHANGED] =
|
file_signals[CHANGED] =
|
||||||
g_signal_newv ("changed",
|
g_signal_newv ("changed",
|
||||||
G_TYPE_FROM_CLASS (gobject_class),
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
@@ -1385,9 +1385,9 @@ file_signals[CHANGED] =
|
|||||||
G_TYPE_NONE /* return_type */,
|
G_TYPE_NONE /* return_type */,
|
||||||
0 /* n_params */,
|
0 /* n_params */,
|
||||||
NULL /* param_types */);
|
NULL /* param_types */);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
and the signal is emitted in <function>maman_file_write</function>:
|
and the signal is emitted in <function>maman_file_write</function>:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void
|
void
|
||||||
maman_file_write (MamanFile *self,
|
maman_file_write (MamanFile *self,
|
||||||
const guchar *buffer,
|
const guchar *buffer,
|
||||||
@@ -1398,7 +1398,7 @@ maman_file_write (MamanFile *self,
|
|||||||
/* Then, notify user of data written. */
|
/* Then, notify user of data written. */
|
||||||
g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
|
g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
As shown above, you can safely set the details parameter to zero if
|
As shown above, you can safely set the details parameter to zero if
|
||||||
you do not know what it can be used for. For a discussion of what you
|
you do not know what it can be used for. For a discussion of what you
|
||||||
could used it for, see <xref linkend="signal-detail"/>
|
could used it for, see <xref linkend="signal-detail"/>
|
||||||
@@ -1451,9 +1451,9 @@ maman_file_write (MamanFile *self,
|
|||||||
To do this, we use our own marshaller which will be generated
|
To do this, we use our own marshaller which will be generated
|
||||||
through GLib's glib-genmarshal tool. We thus create a file named <filename>marshall.list</filename> which contains
|
through GLib's glib-genmarshal tool. We thus create a file named <filename>marshall.list</filename> which contains
|
||||||
the following single line:
|
the following single line:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
VOID:POINTER,UINT
|
VOID:POINTER,UINT
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
and use the Makefile provided in <filename>sample/signal/Makefile</filename> to generate the file named
|
and use the Makefile provided in <filename>sample/signal/Makefile</filename> to generate the file named
|
||||||
<filename>maman-file-complex-marshall.c</filename>. This C file is finally included in
|
<filename>maman-file-complex-marshall.c</filename>. This C file is finally included in
|
||||||
<filename>maman-file-complex.c</filename>.
|
<filename>maman-file-complex.c</filename>.
|
||||||
@@ -1463,7 +1463,7 @@ VOID:POINTER,UINT
|
|||||||
Once the marshaller is present, we register the signal and its marshaller in the class_init function
|
Once the marshaller is present, we register the signal and its marshaller in the class_init function
|
||||||
of the object <type>MamanFileComplex</type> (full source for this object is included in
|
of the object <type>MamanFileComplex</type> (full source for this object is included in
|
||||||
<filename>sample/signal/maman-file-complex.{h|c}</filename>):
|
<filename>sample/signal/maman-file-complex.{h|c}</filename>):
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
GClosure *default_closure;
|
GClosure *default_closure;
|
||||||
GType param_types[2];
|
GType param_types[2];
|
||||||
|
|
||||||
@@ -1484,7 +1484,7 @@ klass->write_signal_id =
|
|||||||
G_TYPE_NONE /* return_type */,
|
G_TYPE_NONE /* return_type */,
|
||||||
2 /* n_params */,
|
2 /* n_params */,
|
||||||
param_types /* param_types */);
|
param_types /* param_types */);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The code shown above first creates the closure which contains the code to complete the file write. This
|
The code shown above first creates the closure which contains the code to complete the file write. This
|
||||||
closure is registered as the default class_closure of the newly created signal.
|
closure is registered as the default class_closure of the newly created signal.
|
||||||
</para>
|
</para>
|
||||||
@@ -1492,7 +1492,7 @@ klass->write_signal_id =
|
|||||||
<para>
|
<para>
|
||||||
Of course, you need to implement completely the code for the default closure since I just provided
|
Of course, you need to implement completely the code for the default closure since I just provided
|
||||||
a skeleton:
|
a skeleton:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer user_data)
|
default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -1500,13 +1500,13 @@ default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer
|
|||||||
/* Here, we trigger the real file write. */
|
/* Here, we trigger the real file write. */
|
||||||
g_print ("default signal handler: 0x%x %u\n", buffer, size);
|
g_print ("default signal handler: 0x%x %u\n", buffer, size);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Finally, the client code must invoke the <function>maman_file_complex_write</function> function which
|
Finally, the client code must invoke the <function>maman_file_complex_write</function> function which
|
||||||
triggers the signal emission:
|
triggers the signal emission:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
|
void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
|
||||||
{
|
{
|
||||||
/* trigger event */
|
/* trigger event */
|
||||||
@@ -1515,7 +1515,7 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
|
|||||||
0, /* details */
|
0, /* details */
|
||||||
buffer, size);
|
buffer, size);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -1531,7 +1531,7 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void complex_write_event_before (GObject *file, guint8 *buffer, guint size, gpointer user_data)
|
static void complex_write_event_before (GObject *file, guint8 *buffer, guint size, gpointer user_data)
|
||||||
{
|
{
|
||||||
g_assert (user_data == NULL);
|
g_assert (user_data == NULL);
|
||||||
@@ -1563,7 +1563,7 @@ static void test_file_complex (void)
|
|||||||
|
|
||||||
g_object_unref (G_OBJECT (file));
|
g_object_unref (G_OBJECT (file));
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The code above generates the following output on my machine:
|
The code above generates the following output on my machine:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
Complex Write event before: 0xbfffe280, 50
|
Complex Write event before: 0xbfffe280, 50
|
||||||
@@ -1618,7 +1618,7 @@ Complex Write event after: 0xbfffe280, 50
|
|||||||
|
|
||||||
<para>The following code shows the declaration of the <type>MamanFileSimple</type> class structure which contains
|
<para>The following code shows the declaration of the <type>MamanFileSimple</type> class structure which contains
|
||||||
the <function>write</function> function pointer.
|
the <function>write</function> function pointer.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
struct _MamanFileSimpleClass {
|
struct _MamanFileSimpleClass {
|
||||||
GObjectClass parent;
|
GObjectClass parent;
|
||||||
|
|
||||||
@@ -1627,10 +1627,10 @@ struct _MamanFileSimpleClass {
|
|||||||
/* signal default handlers */
|
/* signal default handlers */
|
||||||
void (*write) (MamanFileSimple *self, guint8 *buffer, guint size);
|
void (*write) (MamanFileSimple *self, guint8 *buffer, guint size);
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The <function>write</function> function pointer is initialized in the class_init function of the object
|
The <function>write</function> function pointer is initialized in the class_init function of the object
|
||||||
to <function>default_write_signal_handler</function>:
|
to <function>default_write_signal_handler</function>:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
maman_file_simple_class_init (gpointer g_class,
|
maman_file_simple_class_init (gpointer g_class,
|
||||||
gpointer g_class_data)
|
gpointer g_class_data)
|
||||||
@@ -1639,9 +1639,9 @@ maman_file_simple_class_init (gpointer g_class,
|
|||||||
MamanFileSimpleClass *klass = MAMAN_FILE_SIMPLE_CLASS (g_class);
|
MamanFileSimpleClass *klass = MAMAN_FILE_SIMPLE_CLASS (g_class);
|
||||||
|
|
||||||
klass->write = default_write_signal_handler;
|
klass->write = default_write_signal_handler;
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
Finally, the signal is created with <function><link linkend="g-signal-new">g_signal_new</link></function> in the same class_init function:
|
Finally, the signal is created with <function><link linkend="g-signal-new">g_signal_new</link></function> in the same class_init function:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
klass->write_signal_id =
|
klass->write_signal_id =
|
||||||
g_signal_new ("write",
|
g_signal_new ("write",
|
||||||
G_TYPE_FROM_CLASS (g_class),
|
G_TYPE_FROM_CLASS (g_class),
|
||||||
@@ -1654,7 +1654,7 @@ klass->write_signal_id =
|
|||||||
2 /* n_params */,
|
2 /* n_params */,
|
||||||
G_TYPE_POINTER,
|
G_TYPE_POINTER,
|
||||||
G_TYPE_UINT);
|
G_TYPE_UINT);
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
Of note, here, is the 4th argument to the function: it is an integer calculated by the <function><link linkend="G-STRUCT-OFFSET">G_STRUCT_OFFSET</link></function>
|
Of note, here, is the 4th argument to the function: it is an integer calculated by the <function><link linkend="G-STRUCT-OFFSET">G_STRUCT_OFFSET</link></function>
|
||||||
macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the
|
macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the
|
||||||
<type>MamanFileSimpleClass</type> class structure.
|
<type>MamanFileSimpleClass</type> class structure.
|
||||||
@@ -1762,7 +1762,7 @@ klass->write_signal_id =
|
|||||||
<filename>gobject.h</filename> contains the declaration of <link linkend="GObjectClass"><type>GObjectClass</type></link>
|
<filename>gobject.h</filename> contains the declaration of <link linkend="GObjectClass"><type>GObjectClass</type></link>
|
||||||
whose notify class function is the default handler for the <emphasis>notify</emphasis>
|
whose notify class function is the default handler for the <emphasis>notify</emphasis>
|
||||||
signal:
|
signal:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
struct _GObjectClass
|
struct _GObjectClass
|
||||||
{
|
{
|
||||||
GTypeClass g_type_class;
|
GTypeClass g_type_class;
|
||||||
@@ -1773,14 +1773,14 @@ struct _GObjectClass
|
|||||||
void (*notify) (GObject *object,
|
void (*notify) (GObject *object,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<filename>gobject.c</filename>'s <function><link linkend="g-object-do-class-init">g_object_do_class_init</link></function> function
|
<filename>gobject.c</filename>'s <function><link linkend="g-object-do-class-init">g_object_do_class_init</link></function> function
|
||||||
registers the <emphasis>notify</emphasis> signal and initializes this class function
|
registers the <emphasis>notify</emphasis> signal and initializes this class function
|
||||||
to NULL:
|
to NULL:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void
|
static void
|
||||||
g_object_do_class_init (GObjectClass *class)
|
g_object_do_class_init (GObjectClass *class)
|
||||||
{
|
{
|
||||||
@@ -1799,7 +1799,7 @@ g_object_do_class_init (GObjectClass *class)
|
|||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
1, G_TYPE_PARAM);
|
1, G_TYPE_PARAM);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
<function><link linkend="g-signal-new">g_signal_new</link></function> creates a <link linkend="GClosure"><type>GClosure</type></link> which dereferences the
|
<function><link linkend="g-signal-new">g_signal_new</link></function> creates a <link linkend="GClosure"><type>GClosure</type></link> which dereferences the
|
||||||
type's class structure to access the class function pointer and invoke it if it not NULL. The
|
type's class structure to access the class function pointer and invoke it if it not NULL. The
|
||||||
class function is ignored it is set to NULL.
|
class function is ignored it is set to NULL.
|
||||||
|
@@ -56,10 +56,10 @@
|
|||||||
The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
|
The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
|
||||||
in Perl, a variable which holds an integer can be automatically converted to a string given the
|
in Perl, a variable which holds an integer can be automatically converted to a string given the
|
||||||
required context:
|
required context:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
my $tmp = 10;
|
my $tmp = 10;
|
||||||
print "this is an integer converted to a string:" . $tmp . "\n";
|
print "this is an integer converted to a string:" . $tmp . "\n";
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
Of course, it is also often possible to explicitly specify conversions when the default conversions provided
|
Of course, it is also often possible to explicitly specify conversions when the default conversions provided
|
||||||
by the language are not intuitive.
|
by the language are not intuitive.
|
||||||
</para>
|
</para>
|
||||||
@@ -88,7 +88,7 @@ print "this is an integer converted to a string:" . $tmp . "\n";
|
|||||||
<para>
|
<para>
|
||||||
For the sake of discussion, here is a sample C function and the associated 32 bit x86
|
For the sake of discussion, here is a sample C function and the associated 32 bit x86
|
||||||
assembly code generated by GCC on my Linux box:
|
assembly code generated by GCC on my Linux box:
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
static void function_foo (int foo)
|
static void function_foo (int foo)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ int main (int argc, char *argv[])
|
|||||||
|
|
||||||
push $0xa
|
push $0xa
|
||||||
call 0x80482f4 <function_foo>
|
call 0x80482f4 <function_foo>
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
The assembly code shown above is pretty straightforward: the first instruction pushes
|
The assembly code shown above is pretty straightforward: the first instruction pushes
|
||||||
the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls
|
the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls
|
||||||
<function>function_foo</function>. As you can see, C function calls are implemented by
|
<function>function_foo</function>. As you can see, C function calls are implemented by
|
||||||
|
@@ -99,7 +99,7 @@ break g_object_unref if _object == 0xcafebabe
|
|||||||
(a small program part of the libxslt library) to generate the final HTML
|
(a small program part of the libxslt library) to generate the final HTML
|
||||||
output. Other tools can be used to generate PDF output from the source XML.
|
output. Other tools can be used to generate PDF output from the source XML.
|
||||||
The following code excerpt shows what these comments look like.
|
The following code excerpt shows what these comments look like.
|
||||||
<programlisting>
|
<informalexample><programlisting>
|
||||||
/**
|
/**
|
||||||
* gtk_widget_freeze_child_notify:
|
* gtk_widget_freeze_child_notify:
|
||||||
* @widget: a #GtkWidget
|
* @widget: a #GtkWidget
|
||||||
@@ -113,7 +113,7 @@ void
|
|||||||
gtk_widget_freeze_child_notify (GtkWidget *widget)
|
gtk_widget_freeze_child_notify (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
</programlisting>
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Thorough
|
Thorough
|
||||||
|
Reference in New Issue
Block a user