Documentation fixes. Recommend macro type names such as

2007-11-13  Cody Russell  <bratsche@gnome.org>

        * docs/reference/gobject/gobject-docs.sgml:
        * docs/reference/gobject/tut_gsignal.xml:
        * docs/reference/gobject/tut_gtype.xml:
        * docs/reference/gobject/tut_intro.xml:
        * docs/reference/gobject/tut_tools.xml:
        * docs/reference/gobject/tut_howto.xml:
        * docs/reference/gobject/tut_gobject.xml: Documentation fixes.
        Recommend macro type names such as NAUTILUS_TYPE_WINDOW (not
        NAUTILUS_WINDOW_TYPE).  Fixed text which erroneously stated that 
        superclass initializers don't run when an object is 
        instantiated.  Fixed numerous spelling mistakes.  Minor grammar 
        edits. (#490637, Adam Dingle)


svn path=/trunk/; revision=5857
This commit is contained in:
Cody Russell 2007-11-13 07:10:42 +00:00 committed by Cody Russell
parent 1d174f072b
commit 515f42c9ed
8 changed files with 139 additions and 132 deletions

View File

@ -1,3 +1,18 @@
2007-11-13 Cody Russell <bratsche@gnome.org>
* docs/reference/gobject/gobject-docs.sgml:
* docs/reference/gobject/tut_gsignal.xml:
* docs/reference/gobject/tut_gtype.xml:
* docs/reference/gobject/tut_intro.xml:
* docs/reference/gobject/tut_tools.xml:
* docs/reference/gobject/tut_howto.xml:
* docs/reference/gobject/tut_gobject.xml: Documentation fixes.
Recommend macro type names such as NAUTILUS_TYPE_WINDOW (not
NAUTILUS_WINDOW_TYPE). Fixed text which erroneously stated that
superclass initializers don't run when an object is
instantiated. Fixed numerous spelling mistakes. Minor grammar
edits. (#490637, Adam Dingle)
2007-11-09 Matthias Clasen <mclasen@redhat.com> 2007-11-09 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Coding style cleanups and doc * glib/gkeyfile.c: Coding style cleanups and doc

View File

@ -42,7 +42,7 @@
types and algorithms (linked lists, hash tables and so forth), the types and algorithms (linked lists, hash tables and so forth), the
GLib Object System provides the required implementations of a GLib Object System provides the required implementations of a
flexible extensible and intentionally easy to map (into other flexible extensible and intentionally easy to map (into other
languages) object oriented framework for C. languages) object-oriented framework for C.
The substantial elements that are provided can be summarized as: The substantial elements that are provided can be summarized as:
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>

View File

@ -3,7 +3,7 @@
<title>The GObject base class</title> <title>The GObject base class</title>
<para> <para>
The two previous chapters discussed the details of Glib's Dynamic Type System The two previous chapters discussed the details of GLib's Dynamic Type System
and its signal control system. The GObject library also contains an implementation and its signal control system. The GObject library also contains an implementation
for a base fundamental type named <type><link linkend="GObject">GObject</link></type>. for a base fundamental type named <type><link linkend="GObject">GObject</link></type>.
</para> </para>
@ -16,13 +16,13 @@
<listitem><para>Generic per-object properties with set/get function pairs</para></listitem> <listitem><para>Generic per-object properties with set/get function pairs</para></listitem>
<listitem><para>Easy use of signals</para></listitem> <listitem><para>Easy use of signals</para></listitem>
</itemizedlist> </itemizedlist>
All the GNOME libraries which use the GLib type system (like Gtk+ and GStreamer) All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer)
inherit from <type><link linkend="GObject">GObject</link></type> which is why it is important to understand inherit from <type><link linkend="GObject">GObject</link></type> which is why it is important to understand
the details of how it works. the details of how it works.
</para> </para>
<sect1 id="gobject-instanciation"> <sect1 id="gobject-instantiation">
<title>Object instanciation</title> <title>Object instantiation</title>
<para> <para>
The <function><link linkend="g-object-new">g_object_new</link></function> family of functions can be used to instantiate any The <function><link linkend="g-object-new">g_object_new</link></function> family of functions can be used to instantiate any
@ -162,7 +162,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
is how we can find the parent constructor. An approach (used in GTK+ source code) would be is how we can find the parent constructor. An approach (used in GTK+ source code) would be
to save the original constructor in a static variable from <function>maman_bar_class_init</function> to save the original constructor in a static variable from <function>maman_bar_class_init</function>
and then to re-use it from <function>maman_bar_constructor</function>. This is clearly possible and then to re-use it from <function>maman_bar_constructor</function>. This is clearly possible
and very simple but I was told it was not nice and the prefered way is to use the and very simple but I was told it was not nice and the preferred way is to use the
<function><link linkend="g-type-class-peek">g_type_class_peek</link></function> and <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> functions. <function><link linkend="g-type-class-peek">g_type_class_peek</link></function> and <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> functions.
</para> </para>
@ -174,7 +174,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
was registered. After instance_init returns, the object is fully initialized and should be was registered. After instance_init returns, the object is fully initialized and should be
ready to answer any user-request. When <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> ready to answer any user-request. When <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
returns, <function>g_object_constructor</function> sets the construction properties returns, <function>g_object_constructor</function> sets the construction properties
(ie: the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns (i.e. the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns
to the user's constructor which is then allowed to do useful instance initialization... to the user's constructor which is then allowed to do useful instance initialization...
</para> </para>
@ -325,7 +325,7 @@ void g_object_run_dispose (GObject *object);
increase and decrease the reference count.These functions are thread-safe as of GLib 2.8. increase and decrease the reference count.These functions are thread-safe as of GLib 2.8.
The reference count is, unsurprisingly, initialized to one by The reference count is, unsurprisingly, initialized to one by
<function><link linkend="g-object-new">g_object_new</link></function> which means that the caller <function><link linkend="g-object-new">g_object_new</link></function> which means that the caller
is currenly the sole owner of the newly-created reference. is currently the sole owner of the newly-created reference.
When the reference count reaches zero, that is, When the reference count reaches zero, that is,
when <function><link linkend="g-object-unref">g_object_unref</link></function> is called by the last client holding when <function><link linkend="g-object-unref">g_object_unref</link></function> is called by the last client holding
a reference to the object, the <emphasis>dispose</emphasis> and the a reference to the object, the <emphasis>dispose</emphasis> and the
@ -515,7 +515,7 @@ void g_object_run_dispose (GObject *object);
<para> <para>
One of GObject's nice features is its generic get/set mechanism for object One of GObject's nice features is its generic get/set mechanism for object
properties. When an object properties. When an object
is instanciated, the object's class_init handler should be used to register is instantiated, the object's class_init handler should be used to register
the object's properties with <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function> the object's properties with <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>
(implemented in <filename>gobject.c</filename>). (implemented in <filename>gobject.c</filename>).
</para> </para>
@ -657,7 +657,7 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
relying on these transformations. relying on these transformations.
</para> </para>
</footnote> </footnote>
which matches and conversion will be caried out if needed. which matches and conversion will be carried out if needed.
</para> </para>
<para> <para>
@ -704,12 +704,12 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
property modifications through the "notify" signal. It is important to remember that property modifications through the "notify" signal. It is important to remember that
even if properties are changed while property change notification is frozen, the "notify" even if properties are changed while property change notification is frozen, the "notify"
signal will be emitted once for each of these changed properties as soon as the property signal will be emitted once for each of these changed properties as soon as the property
change notification is thawn: no property change is lost for the "notify" signal. Signal change notification is thawed: no property change is lost for the "notify" signal. Signal
can only be delayed by the notification freezing mechanism. can only be delayed by the notification freezing mechanism.
</para> </para>
<para> <para>
It sounds like a tedious task to set up GValues everytime when one wants to modify a property. It sounds like a tedious task to set up GValues every time when one wants to modify a property.
In practice one will rarely do this. The functions <function><link linkend="g-object-set-property">g_object_set_property</link></function> In practice one will rarely do this. The functions <function><link linkend="g-object-set-property">g_object_set_property</link></function>
and <function><link linkend="g-object-get-property">g_object_get_property</link></function> and <function><link linkend="g-object-get-property">g_object_get_property</link></function>
are meant to be used by language bindings. For application there is an easier way and are meant to be used by language bindings. For application there is an easier way and
@ -760,7 +760,7 @@ g_object_set (G_OBJECT (foo),
</sect2> </sect2>
<!-- @todo tell here about how to pass use handle properties in derived classe --> <!-- @todo tell here about how to pass use handle properties in derived classes -->
</sect1> </sect1>

View File

@ -7,7 +7,7 @@
<para> <para>
Closures are central to the concept of asynchronous signal delivery Closures are central to the concept of asynchronous signal delivery
which is widely used throughout GTK+ and GNOME applications. A Closure is an which is widely used throughout GTK+ and GNOME applications. A closure is an
abstraction, a generic representation of a callback. It is a small structure abstraction, a generic representation of a callback. It is a small structure
which contains three objects: which contains three objects:
<itemizedlist> <itemizedlist>
@ -32,12 +32,12 @@ return_type function_callback (... , gpointer user_data);
closure implementations: there exists a different Closure implementation for closure implementations: there exists a different Closure implementation for
each separate runtime which wants to use the GObject type system. each separate runtime which wants to use the GObject type system.
<footnote><para> <footnote><para>
In Practice, Closures sit at the boundary of language runtimes: if you are In practice, closures sit at the boundary of language runtimes: if you are
writing python code and one of your Python callback receives a signal from writing Python code and one of your Python callbacks receives a signal from
one of GTK+ widgets, the C code in GTK+ needs to execute your Python a GTK+ widget, the C code in GTK+ needs to execute your Python
code. The Closure invoked by the GTK+ object invokes the Python callback: code. The closure invoked by the GTK+ object invokes the Python callback:
it behaves as a normal C object for GTK+ and as a normal Python object for it behaves as a normal C object for GTK+ and as a normal Python object for
python code. Python code.
</para></footnote> </para></footnote>
The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which
is a specific implementation of closures to be used with C/C++ callbacks. is a specific implementation of closures to be used with C/C++ callbacks.
@ -48,7 +48,7 @@ return_type function_callback (... , gpointer user_data);
<listitem><para> <listitem><para>
Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures
were created for: they hide the details of callback invocation from the were created for: they hide the details of callback invocation from the
callback invocator.</para> callback invoker.</para>
</listitem> </listitem>
<listitem><para> <listitem><para>
Notification: the closure notifies listeners of certain events such as Notification: the closure notifies listeners of certain events such as
@ -57,12 +57,12 @@ return_type function_callback (... , gpointer user_data);
(finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function> (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
(invalidation notification) and (invalidation notification) and
<function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification). <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
There exist symmetric de-registration functions for finalization and invalidation There exist symmetric deregistration functions for finalization and invalidation
events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
<function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
process. process.
<footnote><para> <footnote><para>
Closures are refcounted and notify listeners of their destruction in a two-stage Closures are reference counted and notify listeners of their destruction in a two-stage
process: the invalidation notifiers are invoked before the finalization notifiers. process: the invalidation notifiers are invoked before the finalization notifiers.
</para></footnote></para> </para></footnote></para>
</listitem> </listitem>
@ -74,7 +74,7 @@ return_type function_callback (... , gpointer user_data);
<para> <para>
If you are using C or C++ If you are using C or C++
to connect a callback to a given event, you will either use the simple <type><link linkend="GCClosure">GCClosure</link></type>s to connect a callback to a given event, you will either use simple <type><link linkend="GCClosure">GCClosure</link></type>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> <programlisting>
@ -106,10 +106,10 @@ GClosure* g_signal_type_cclosure_new (GType itype,
</sect2> </sect2>
<sect2> <sect2>
<title>non-C closures (for the fearless).</title> <title>Non-C closures (for the fearless)</title>
<para> <para>
As was explained above, Closures hide the details of callback invocation. In C, As was explained above, closures hide the details of callback invocation. In C,
callback invocation is just like function invocation: it is a matter of creating callback invocation is just like function invocation: it is a matter of creating
the correct stack frame for the called function and executing a <emphasis>call</emphasis> the correct stack frame for the called function and executing a <emphasis>call</emphasis>
assembly instruction. assembly instruction.
@ -156,12 +156,12 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
<para> <para>
Of course, there exist other kinds of marshallers. For example, James Henstridge Of course, there exist other kinds of marshallers. For example, James Henstridge
wrote a generic Python marshaller which is used by all python Closures (a python closure wrote a generic Python marshaller which is used by all Python closures (a Python closure
is used to have python-based callback be invoked by the closure invocation process). is used to have Python-based callback be invoked by the closure invocation process).
This python marshaller transforms the input GValue list representing the function This Python marshaller transforms the input GValue list representing the function
parameters into a Python tuple which is the equivalent structure in python (you can parameters into a Python tuple which is the equivalent structure in Python (you can
look in <function>pyg_closure_marshal</function> in <filename>pygtype.c</filename> look in <function>pyg_closure_marshal</function> in <filename>pygtype.c</filename>
in the <emphasis>pygobject</emphasis> module in GNOME cvs server). in the <emphasis>pygobject</emphasis> module in the GNOME Subversion server).
</para> </para>
</sect2> </sect2>

View File

@ -1,9 +1,9 @@
<?xml version='1.0' encoding="ISO-8859-1"?> <?xml version='1.0' encoding="ISO-8859-1"?>
<chapter id="chapter-gtype"> <chapter id="chapter-gtype">
<title>The Glib Dynamic Type System</title> <title>The GLib Dynamic Type System</title>
<para> <para>
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> <programlisting>
@ -53,7 +53,7 @@ GType g_type_register_fundamental (GType type_id,
new fundamental types. new fundamental types.
<footnote> <footnote>
<para> <para>
Please, note that there exist another registration function: the Please note that there exists another registration function: the
<function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>. We will not discuss this <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>. We will not discuss this
function here since its use is very similar to the <function>_static</function> function here since its use is very similar to the <function>_static</function>
version. version.
@ -71,7 +71,7 @@ GType g_type_register_fundamental (GType type_id,
</para> </para>
<para> <para>
Fundamental and non-Fundamental types are defined by: Fundamental and non-fundamental types are defined by:
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
class size: the class_size field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>. class size: the class_size field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
@ -89,7 +89,7 @@ GType g_type_register_fundamental (GType type_id,
<type><link linkend="GTypeInfo">GTypeInfo</link></type>. <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
instanciation policy (C++ type of new operator): the n_preallocs instantiation policy (C++ type of new operator): the n_preallocs
field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>. field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
@ -102,7 +102,7 @@ GType g_type_register_fundamental (GType type_id,
</itemizedlist> </itemizedlist>
Fundamental types are also defined by a set of <type><link linkend="GTypeFundamentalFlags">GTypeFundamentalFlags</link></type> Fundamental types are also defined by a set of <type><link linkend="GTypeFundamentalFlags">GTypeFundamentalFlags</link></type>
which are stored in a <type><link linkend="GTypeFundamentalInfo">GTypeFundamentalInfo</link></type>. which are stored in a <type><link linkend="GTypeFundamentalInfo">GTypeFundamentalInfo</link></type>.
Non-Fundamental types are furthermore defined by the type of their parent which is Non-fundamental types are furthermore defined by the type of their parent which is
passed as the parent_type parameter to <function><link linkend="g-type-register-static">g_type_register_static</link></function> passed as the parent_type parameter to <function><link linkend="g-type-register-static">g_type_register_static</link></function>
and <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>. and <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>.
</para> </para>
@ -111,7 +111,7 @@ GType g_type_register_fundamental (GType type_id,
<title>Copy functions</title> <title>Copy functions</title>
<para> <para>
The major common point between <emphasis>all</emphasis> glib types (fundamental and The major common point between <emphasis>all</emphasis> GLib types (fundamental and
non-fundamental, classed and non-classed, instantiable and non-instantiable) is that non-fundamental, classed and non-classed, instantiable and non-instantiable) is that
they can all be manipulated through a single API to copy/assign them. they can all be manipulated through a single API to copy/assign them.
</para> </para>
@ -177,7 +177,7 @@ static void test_object (void)
g_object_unref (G_OBJECT (obj)); g_object_unref (G_OBJECT (obj));
} }
</programlisting> </programlisting>
The important point about the above code is that the exact semantic 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
data from the source to the destination. Others might want to simply increment data from the source to the destination. Others might want to simply increment
@ -215,7 +215,7 @@ struct _GTypeValueTable
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
non-fundamental types which means that unless you want to write a non-fundamental types which means that unless you want to write a
fundamental type (not a great idea !), you will not need to provide fundamental type (not a great idea!), you will not need to provide
a new value_table since you will inherit the value_table structure a new value_table since you will inherit the value_table structure
from your parent type. from your parent type.
</para> </para>
@ -238,7 +238,7 @@ struct _GTypeValueTable
If your library (or application) is named <emphasis>Maman</emphasis>, If your library (or application) is named <emphasis>Maman</emphasis>,
<footnote> <footnote>
<para> <para>
<emphasis>Maman</emphasis> is the french word for <emphasis>mum</emphasis> <emphasis>Maman</emphasis> is the French word for <emphasis>mum</emphasis>
or <emphasis>mother</emphasis> - nothing more and nothing less. or <emphasis>mother</emphasis> - nothing more and nothing less.
</para> </para>
</footnote> </footnote>
@ -329,7 +329,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
</sect1> </sect1>
<sect1 id="gtype-non-instantiable"> <sect1 id="gtype-non-instantiable">
<title>Non-Instantiable non-classed fundamental types</title> <title>Non-instantiable non-classed fundamental types</title>
<para> <para>
A lot of types are not instantiable by the type system and do not have A lot of types are not instantiable by the type system and do not have
@ -372,7 +372,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
<para> <para>
Having non-instantiable types might seem a bit useless: what good is a type Having non-instantiable types might seem a bit useless: what good is a type
if you cannot instanciate an instance of that type ? Most of these types if you cannot instantiate an instance of that type ? Most of these types
are used in conjunction with <type><link linkend="GValue">GValue</link></type>s: a GValue is initialized are used in conjunction with <type><link linkend="GValue">GValue</link></type>s: a GValue is initialized
with an integer or a string and it is passed around by using the registered with an integer or a string and it is passed around by using the registered
type's value_table. <type><link linkend="GValue">GValue</link></type>s (and by extension these trivial fundamental type's value_table. <type><link linkend="GValue">GValue</link></type>s (and by extension these trivial fundamental
@ -390,7 +390,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
Although <type><link linkend="GObject">GObject</link></type>s (detailed in <xref linkend="chapter-gobject"/>) Although <type><link linkend="GObject">GObject</link></type>s (detailed in <xref linkend="chapter-gobject"/>)
are the most well known type of instantiable are the most well known type of instantiable
classed types, other kinds of similar objects used as the base of an inheritance classed types, other kinds of similar objects used as the base of an inheritance
hierarchy have been externally developped and they are all built on the fundamental hierarchy have been externally developed and they are all built on the fundamental
features described below. features described below.
</para> </para>
@ -515,14 +515,14 @@ B *b;
<title>Initialization and Destruction</title> <title>Initialization and Destruction</title>
<para> <para>
Instanciation 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> <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>
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will lookup 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 instanciation 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
the object's instance structures in chunks rather than mallocing for every instance) the object's instance structures in chunks rather than mallocing for every instance)
declared by the user are used to get a buffer to hold the object's instance declared by the user are used to get a buffer to hold the object's instance
@ -569,7 +569,7 @@ void g_type_free_instance (GTypeInstance *instance);
(in <filename>gtype.c</filename>. (in <filename>gtype.c</filename>.
</para> </para>
</footnote> </footnote>
(the concept of destruction is sometimes partly refered to as finalization (the concept of destruction is sometimes partly referred to as finalization
in GType) is the symmetric process of the initialization: interfaces are in GType) is the symmetric process of the initialization: interfaces are
destroyed first. destroyed first.
Then, the most derived Then, the most derived
@ -581,27 +581,19 @@ void g_type_free_instance (GTypeInstance *instance);
<para> <para>
As many readers have now understood it, the base initialization/finalization process is As many readers have now understood it, the base initialization/finalization process is
very similar to the C++ Constructor/Destructor paradigm. The practical details are quite different very similar to the C++ constructor/destructor paradigm. The practical details are different
though and it is important not to get confused by the superficial similarities. Typically, what though and it is important not to get confused by superficial similarities.
most users have grown to know as a C++ constructor (that is, a list of
object methods invoked on the object instance once for each type of the inheritance hierachy) does
not exist in GType and must be built on top of the facilities offered by GType. Similarly,
GTypes have no instance destruction mechanism. It is GTypes have no instance destruction mechanism. It is
the user's responsibility to implement correct destruction semantics on top the user's responsibility to implement correct destruction semantics on top
of the existing GType code. (this is what GObject does. See of the existing GType code. (this is what GObject does. See
<xref linkend="chapter-gobject"/>) <xref linkend="chapter-gobject"/>)
</para> Furthermore, C++ code equivalent to the base_init
<para>
For example, if the object B which derives from A is instantiated, GType will only invoke the
instance_init callback of object B while a C++ runtime will invoke the constructor of the object
type A first and then of the object type B. Furthermore, the C++ code equivalent to the base_init
and class_init callbacks of GType is usually not needed because C++ cannot really create object and class_init callbacks of GType is usually not needed because C++ cannot really create object
types at runtime. types at runtime.
</para> </para>
<para> <para>
The instanciation/finalization process can be summarized as follows: The instantiation/finalization process can be summarized as follows:
<table id="gtype-init-fini-table"> <table id="gtype-init-fini-table">
<title>GType Instantiation/Finalization</title> <title>GType Instantiation/Finalization</title>
<tgroup cols="3"> <tgroup cols="3">
@ -666,15 +658,15 @@ void g_type_free_instance (GTypeInstance *instance);
</sect1> </sect1>
<sect1 id="gtype-non-instantiable-classed"> <sect1 id="gtype-non-instantiable-classed">
<title>Non-instantiable classed types: Interfaces.</title> <title>Non-instantiable classed types: interfaces</title>
<para> <para>
GType's Interfaces are very similar to Java's interfaces. They allow GType's interfaces are very similar to Java's interfaces. They allow
to describe a common API that several classes will adhere to. to describe a common API that several classes will adhere to.
Imagine the play, pause and stop buttons on hifi equipment - those can Imagine the play, pause and stop buttons on hi-fi equipment - those can
be seen as a playback interface. Once you know what the do, you can be seen as a playback interface. Once you know what they do, you can
control your cd-player, mp3-player or anything that uses these symbols. control your CD player, MP3 player or anything that uses these symbols.
To declare an interfacce 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
<type><link linkend="GTypeInterface">GTypeInterface</link></type>. The following piece of code declares such an interface. <type><link linkend="GTypeInterface">GTypeInterface</link></type>. The following piece of code declares such an interface.
<programlisting> <programlisting>
@ -886,7 +878,7 @@ maman_ibaz_base_init (gpointer g_iface)
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
It is highly unlikely (ie: I do not know of <emphasis>anyone</emphasis> who actually It is highly unlikely (i.e. I do not know of <emphasis>anyone</emphasis> who actually
used it) you will ever need other more fancy things such as the ones described in the used it) you will ever need other more fancy things such as the ones described in the
following section (<xref linkend="gtype-non-instantiable-classed-dest"/>). following section (<xref linkend="gtype-non-instantiable-classed-dest"/>).
</para> </para>

View File

@ -2,20 +2,20 @@
<partintro> <partintro>
<para> <para>
This chapter tries to answer the real-life questions of users and presents This chapter tries to answer the real-life questions of users and presents
the most common scenario use-cases I could come up with. the most common scenario use cases I could come up with.
The use-cases are presented from most likely to less likely. The use cases are presented from most likely to less likely.
</para> </para>
</partintro> </partintro>
<chapter id="howto-gobject"> <chapter id="howto-gobject">
<title>How To define and implement a new GObject?</title> <title>How to define and implement a new GObject</title>
<para> <para>
Clearly, this is one of the most common question people ask: they just want to crank code and Clearly, this is one of the most common questions people ask: they just want to crank code and
implement a subclass of a GObject. Sometimes because they want to create their own class hierarchy, implement a subclass of a GObject. Sometimes because they want to create their own class hierarchy,
sometimes because they want to subclass one of GTK+'s widget. This chapter will focus on the sometimes because they want to subclass one of GTK+'s widget. This chapter will focus on the
implementation of a subtype of GObject. The sample source code implementation of a subtype of GObject. The sample source code
associated to this section can be found in the documentation's source tarball, in the associated with this section can be found in the documentation's source tarball, in the
<filename>sample/gobject</filename> directory: <filename>sample/gobject</filename> directory:
<itemizedlist> <itemizedlist>
<listitem><para><filename>maman-bar.{h|c}</filename>: this is the source for a object which derives from <listitem><para><filename>maman-bar.{h|c}</filename>: this is the source for a object which derives from
@ -42,7 +42,7 @@
which is followed not only by GTK+'s code but also by most users of GObject. If you feel the need which is followed not only by GTK+'s code but also by most users of GObject. If you feel the need
not to obey the rules stated below, think about it twice: not to obey the rules stated below, think about it twice:
<itemizedlist> <itemizedlist>
<listitem><para>If your users are a bit accustomed to GTK+ code or any Glib code, they will <listitem><para>If your users are a bit accustomed to GTK+ code or any GLib code, they will
be a bit surprised and getting used to the conventions you decided upon will take time (money) and be a bit surprised and getting used to the conventions you decided upon will take time (money) and
will make them grumpy (not a good thing) will make them grumpy (not a good thing)
</para></listitem> </para></listitem>
@ -84,7 +84,7 @@
<para> <para>
The basic conventions for any header which exposes a GType are described in The basic conventions for any header which exposes a GType are described in
<xref linkend="gtype-conventions"/>. Most GObject-based code also obeys onf of the following <xref linkend="gtype-conventions"/>. Most GObject-based code also obeys one of of the following
conventions: pick one and stick to it. conventions: pick one and stick to it.
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
@ -121,7 +121,7 @@ struct _MamanBarClass {
/* class members */ /* class members */
}; };
/* used by MAMAN_BAR_TYPE */ /* used by MAMAN_TYPE_BAR */
GType maman_bar_get_type (void); GType maman_bar_get_type (void);
/* /*
@ -181,13 +181,13 @@ maman_bar_init (GTypeInstance *instance, gpointer g_class) {
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
A similar alternative, available since Glib version 2.4, is to define a private structure in the .c file, A similar alternative, available since GLib version 2.4, is to define a private structure in the .c file,
declare it as a private structure in <function>maman_bar_class_init</function> using declare it as a private structure in <function>maman_bar_class_init</function> using
<function><link linkend="g-type-class-add-private">g_type_class_add_private</link></function>. <function><link linkend="g-type-class-add-private">g_type_class_add_private</link></function>.
Instead of allocating memory in <function>maman_bar_init</function> a pointer to the private memory area is Instead of allocating memory in <function>maman_bar_init</function> a pointer to the private memory area is
stored in the instance to allow convenient access to this structure. stored in the instance to allow convenient access to this structure.
A private structure will then be attached to each newly created object by the GObject system. A private structure will then be attached to each newly created object by the GObject system.
You dont need to free or allocate the private structure, only the objects or pointers that it may contain. You don't need to free or allocate the private structure, only the objects or pointers that it may contain.
Another advantage of this to the previous version is that is lessens memory fragmentation, Another advantage of this to the previous version is that is lessens memory fragmentation,
as the public and private parts of the instance memory are allocated at once. as the public and private parts of the instance memory are allocated at once.
<programlisting> <programlisting>
@ -208,7 +208,7 @@ maman_bar_class_init (MamanBarClass *klass)
static void static void
maman_bar_init (GTypeInstance *instance, gpointer g_class) { maman_bar_init (GTypeInstance *instance, gpointer g_class) {
MamanBar *self = MAMAN_BAR (instance); MamanBar *self = MAMAN_BAR (instance);
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MAMAN_BAR_TYPE, MamanBarPrivate); self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MAMAN_TYPE_BAR, MamanBarPrivate);
/* do stuff */ /* do stuff */
} }
</programlisting> </programlisting>
@ -308,7 +308,7 @@ maman_bar_get_type (void)
<para> <para>
<xref linkend="gobject-construction-table"/> shows what user-provided functions <xref linkend="gobject-construction-table"/> shows what user-provided functions
are invoked during object instanciation and in which order they are invoked. are invoked during object instantiation and in which order they are invoked.
A user looking for the equivalent of the simple C++ constructor function should use A user looking for the equivalent of the simple C++ constructor function should use
the instance_init method. It will be invoked after all the parent's instance_init the instance_init method. It will be invoked after all the parent's instance_init
functions have been invoked. It cannot take arbitrary construction parameters functions have been invoked. It cannot take arbitrary construction parameters
@ -333,7 +333,7 @@ maman_bar_init (GTypeInstance *instance,
self->private = g_new0 (MamanBarPrivate, 1); self->private = g_new0 (MamanBarPrivate, 1);
/* initialize all public and private members to reasonable default values. */ /* initialize all public and private members to reasonable default values. */
/* If you need specific consruction properties to complete initialization, /* If you need specific construction properties to complete initialization,
* delay initialization completion until the property is set. * delay initialization completion until the property is set.
*/ */
} }
@ -386,7 +386,7 @@ bar_class_init (MamanBarClass *klass)
<para>Some people sometimes need to construct their object but only after the construction properties <para>Some people sometimes need to construct their object but only after the construction properties
have been set. This is possible through the use of the constructor class method as described in have been set. This is possible through the use of the constructor class method as described in
<xref linkend="gobject-instanciation"/>. However, I have yet to see <emphasis>any</emphasis> reasonable <xref linkend="gobject-instantiation"/>. However, I have yet to see <emphasis>any</emphasis> reasonable
use of this feature. As such, to initialize your object instances, use by default the base_init function use of this feature. As such, to initialize your object instances, use by default the base_init function
and construction properties. and construction properties.
</para> </para>
@ -685,21 +685,21 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
<itemizedlist> <itemizedlist>
<listitem><para>You need to change the behaviour of a class without modifying its code. You create <listitem><para>You need to change the behaviour of a class without modifying its code. You create
a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour
slightly and chain up to ensure that the previous behaviour is not really modifed, just extended. slightly and chain up to ensure that the previous behaviour is not really modified, just extended.
</para></listitem> </para></listitem>
<listitem><para>You are lazy, you have access to the source code of the parent class but you don't want <listitem><para>You are lazy, you have access to the source code of the parent class but you don't want
to modify it to add method calls to new specialized method calls: it is faster to hack the child class to modify it to add method calls to new specialized method calls: it is faster to hack the child class
to chain up than to modify the parent to call down.</para></listitem> to chain up than to modify the parent to call down.</para></listitem>
<listitem><para>You need to implement the Chain Of Responsability pattern: each object of the inheritance <listitem><para>You need to implement the Chain Of Responsibility pattern: each object of the inheritance
tree chains up to its parent (typically, at the begining or the end of the method) to ensure that tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that
they each handler is run in turn.</para></listitem> they each handler is run in turn.</para></listitem>
</itemizedlist> </itemizedlist>
I am personally not really convinced any of the last two uses are really a good idea but since this I am personally not really convinced any of the last two uses are really a good idea but since this
programming idiom is often used, this section attemps to explain how to implement it. programming idiom is often used, this section attempts to explain how to implement it.
</para> </para>
<para> <para>
To explicitely chain up to the implementation of the virtual method in the parent class, To explicitly chain up to the implementation of the virtual method in the parent class,
you first need a handle to the original parent class structure. This pointer can then be used to you first need a handle to the original parent class structure. This pointer can then be used to
access the original class function pointer and invoke it directly. access the original class function pointer and invoke it directly.
<footnote> <footnote>
@ -746,10 +746,10 @@ b_method_to_call (B *obj, int a)
<chapter id="howto-interface"> <chapter id="howto-interface">
<title>How To define and implement Interfaces?</title> <title>How to define and implement interfaces</title>
<sect1 id="howto-interface-define"> <sect1 id="howto-interface-define">
<title>How To define Interfaces?</title> <title>How to define interfaces</title>
<para> <para>
The bulk of interface definition has already been shown in <xref linkend="gtype-non-instantiable-classed"/> The bulk of interface definition has already been shown in <xref linkend="gtype-non-instantiable-classed"/>
@ -814,7 +814,7 @@ void maman_ibaz_do_action (MamanIbaz *self);
to make sure not to run the initialization code twice (as described in to make sure not to run the initialization code twice (as described in
<xref linkend="gtype-non-instantiable-classed-init"/>, <xref linkend="gtype-non-instantiable-classed-init"/>,
<function>base_init</function> is run once for each interface implementation <function>base_init</function> is run once for each interface implementation
instanciation)</para></listitem> instantiation)</para></listitem>
<listitem><para><function>maman_ibaz_do_action</function> dereferences the class <listitem><para><function>maman_ibaz_do_action</function> dereferences the class
structure to access its associated class function and calls it. structure to access its associated class function and calls it.
</para></listitem> </para></listitem>
@ -1089,7 +1089,7 @@ maman_bar_get_type (void)
<title>Interface Properties</title> <title>Interface Properties</title>
<para> <para>
Starting from version 2.4 of glib, GObject interfaces can also have properties. Starting from version 2.4 of GLib, GObject interfaces can also have properties.
Declaration of the interface properties is similar to declaring the properties of Declaration of the interface properties is similar to declaring the properties of
ordinary GObject types as explained in <xref linkend="gobject-properties"/>, ordinary GObject types as explained in <xref linkend="gobject-properties"/>,
except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to
@ -1135,7 +1135,7 @@ maman_ibaz_base_init (gpointer g_iface)
<para> <para>
One point worth noting is that the declared property wasn't assigned an One point worth noting is that the declared property wasn't assigned an
integer ID. The reason being that integer IDs of properities are utilized only integer ID. The reason being that integer IDs of properties are utilized only
inside the get and set methods and since interfaces do not implement properties, inside the get and set methods and since interfaces do not implement properties,
there is no need to assign integer IDs to interface properties. there is no need to assign integer IDs to interface properties.
</para> </para>
@ -1146,7 +1146,7 @@ maman_ibaz_base_init (gpointer g_iface)
explained in <xref linkend="gobject-properties"/>, except for one small explained in <xref linkend="gobject-properties"/>, except for one small
change: it shall declare the properties of the interface it implements using change: it shall declare the properties of the interface it implements using
<function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function> instead of <function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function> instead of
<function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>. The following code snipet <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 <type>MamanBaz</type> declaration and shows the modifications needed in the <type>MamanBaz</type> declaration and
implementation above: implementation above:
<programlisting> <programlisting>
@ -1260,14 +1260,14 @@ maman_baz_get_property (GObject * object, guint prop_id,
<!-- End Howto Interfaces --> <!-- End Howto Interfaces -->
<chapter id="howto-signals"> <chapter id="howto-signals">
<title>Howto create and use signals</title> <title>How to create and use signals</title>
<para> <para>
The signal system which was built in GType is pretty complex and flexible: it is possible for its users The signal system which was built in GType is pretty complex and flexible: it is possible for its users
to connect at runtime any number of callbacks (implemented in any language for which a binding exists) to connect at runtime any number of callbacks (implemented in any language for which a binding exists)
<footnote> <footnote>
<para>A python callback can be connected to any signal on any C-based GObject. <para>A Python callback can be connected to any signal on any C-based GObject.
</para> </para>
</footnote> </footnote>
@ -1311,7 +1311,7 @@ klass->write_signal_id =
0 /* n_params */, 0 /* n_params */,
NULL /* param_types */); NULL /* param_types */);
</programlisting> </programlisting>
and the signal is emited in <function>maman_file_write</function>: and the signal is emitted in <function>maman_file_write</function>:
<programlisting> <programlisting>
void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size) void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
{ {
@ -1330,7 +1330,7 @@ void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
The signature of the signal handler in the above example is defined as The signature of the signal handler in the above example is defined as
<function>g_cclosure_marshal_VOID__VOID</function>. Its name follows <function>g_cclosure_marshal_VOID__VOID</function>. Its name follows
a simple convention which encodes the function parameter and return value a simple convention which encodes the function parameter and return value
types in the function name. Specifically, the value infront of the double types in the function name. Specifically, the value in front of the double
underscore is the type of the return value, while the value(s) after the underscore is the type of the return value, while the value(s) after the
double underscore denote the parameter types. double underscore denote the parameter types.
The header <filename>gobject/gmarshal.h</filename> defines a set of commonly The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
@ -1357,7 +1357,7 @@ void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
<para> <para>
The first step to implement this idea is to change the signature of the signal: we need to pass The first step to implement this idea is to change the signature of the signal: we need to pass
around the buffer to write and its size. To do this, we use our own marshaller which will be generated around the buffer to write and its size. To do this, we use our own marshaller which will be generated
through glib's genmarshall tool. We thus create a file named <filename>marshall.list</filename> which contains through GLib's genmarshall tool. We thus create a file named <filename>marshall.list</filename> which contains
the following single line: the following single line:
<programlisting> <programlisting>
VOID:POINTER,UINT VOID:POINTER,UINT
@ -1488,11 +1488,11 @@ Complex Write event after: 0xbfffe280, 50
there is a much <emphasis>simpler</emphasis> there is a much <emphasis>simpler</emphasis>
<footnote> <footnote>
<para>I personally think that this method is horribly mind-twisting: it adds a new indirection <para>I personally think that this method is horribly mind-twisting: it adds a new indirection
which unecessarily complicates the overall code path. However, because this method is widely used which unnecessarily complicates the overall code path. However, because this method is widely used
by all of GTK+ and GObject code, readers need to understand it. The reason why this is done that way by all of GTK+ and GObject code, readers need to understand it. The reason why this is done that way
in most of GTK+ is related to the fact that the ancestor of GObject did not provide any other way to in most of GTK+ is related to the fact that the ancestor of GObject did not provide any other way to
create a signal with a default handler than this one. Some people have tried to justify that it is done create a signal with a default handler than this one. Some people have tried to justify that it is done
that way because it is better, faster (I am extremly doubtfull about the faster bit. As a matter of fact, that way because it is better, faster (I am extremely doubtful about the faster bit. As a matter of fact,
the better bit also mystifies me ;-). I have the feeling no one really knows and everyone does it the better bit also mystifies me ;-). I have the feeling no one really knows and everyone does it
because they copy/pasted code from code which did the same. It is probably better to leave this because they copy/pasted code from code which did the same. It is probably better to leave this
specific trivia to hacker legends domain... specific trivia to hacker legends domain...
@ -1527,7 +1527,7 @@ struct _MamanFileSimpleClass {
void (*write) (MamanFileSimple *self, guint8 *buffer, guint size); void (*write) (MamanFileSimple *self, guint8 *buffer, guint size);
}; };
</programlisting> </programlisting>
The <function>write</function> function pointer is initialied 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> <programlisting>
static void static void
@ -1565,7 +1565,7 @@ klass->write_signal_id =
</para> </para>
<para> <para>
While the complete code for this type of default handler looks less clutered as shown in While the complete code for this type of default handler looks less cluttered as shown in
<filename>sample/signal/maman-file-simple.{h|c}</filename>, it contains numerous subtleties. <filename>sample/signal/maman-file-simple.{h|c}</filename>, it contains numerous subtleties.
The main subtle point which everyone must be aware of is that the signature of the default The main subtle point which everyone must be aware of is that the signature of the default
handler created that way does not have a user_data argument: handler created that way does not have a user_data argument:
@ -1600,7 +1600,7 @@ klass->write_signal_id =
<itemizedlist> <itemizedlist>
<listitem><para>stop the emission of the signal at anytime</para></listitem> <listitem><para>stop the emission of the signal at anytime</para></listitem>
<listitem><para>override the default handler of the signal if it is stored as a function <listitem><para>override the default handler of the signal if it is stored as a function
pointer in the class structure (which is the prefered way to create a default signal handler, pointer in the class structure (which is the preferred way to create a default signal handler,
as discussed in the previous section).</para></listitem> as discussed in the previous section).</para></listitem>
</itemizedlist> </itemizedlist>
</para> </para>

View File

@ -13,10 +13,10 @@
</para> </para>
<para> <para>
A lot of programmers are used to work with compiled-only or dynamically interpreted-only A lot of programmers are used to working with compiled-only or dynamically interpreted-only
languages and do not understand the challenges associated with cross-language interoperability. languages and do not understand the challenges associated with cross-language interoperability.
This introduction tries to provide an insight into these challenges. describes briefly This introduction tries to provide an insight into these challenges and briefly describes
the solution choosen by GLib. the solution chosen by GLib.
</para> </para>
<para> <para>
@ -47,7 +47,7 @@
</para> </para>
<para> <para>
Perl and Python which are interpreted languages do not really provide type definitions similar Perl and Python are interpreted languages which do not really provide type definitions similar
to those used by C. Perl and Python programmers manipulate variables and the type of the variables to those used by C. Perl and Python programmers manipulate variables and the type of the variables
is decided only upon the first assignment or upon the first use which forces a type on the variable. is decided only upon the first assignment or upon the first use which forces a type on the variable.
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,
@ -57,7 +57,7 @@
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>
Of course, it is also often possible to explicitely 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>
@ -79,12 +79,12 @@ print "this is an integer converted to a string:" . $tmp . "\n";
function calling convention and the mapping of the C types to the machine types used by the platform you function calling convention and the mapping of the C types to the machine types used by the platform you
are on, you can resolve the name of each function to find where the code associated to this function are on, you can resolve the name of each function to find where the code associated to this function
is located in memory, and then construct a valid argument list for the function. Finally, all you have to is located in memory, and then construct a valid argument list for the function. Finally, all you have to
do is triger a call to the target C function with the argument list. do is trigger a call to the target C function with the argument list.
</para> </para>
<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> <programlisting>
static void function_foo (int foo) static void function_foo (int foo)
{} {}
@ -101,35 +101,35 @@ push $0xa
call 0x80482f4 &lt;function_foo> call 0x80482f4 &lt;function_foo>
</programlisting> </programlisting>
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
gcc by native function calls (this is probably the fastest implementation possible). gcc by native function calls (this is probably the fastest implementation possible).
</para> </para>
<para> <para>
Now, let's say we want to call the C function <function>function_foo</function> from Now, let's say we want to call the C function <function>function_foo</function> from
a python program. To do this, the python interpreter needs to: a Python program. To do this, the Python interpreter needs to:
<itemizedlist> <itemizedlist>
<listitem><para>Find where the function is located. This means probably find the binary generated by the C compiler <listitem><para>Find where the function is located. This probably means finding the binary generated by the C compiler
which exports this functions.</para></listitem> which exports this function.</para></listitem>
<listitem><para>Load the code of the function in executable memory.</para></listitem> <listitem><para>Load the code of the function in executable memory.</para></listitem>
<listitem><para>Convert the python parameters to C-compatible parameters before calling <listitem><para>Convert the Python parameters to C-compatible parameters before calling
the function.</para></listitem> the function.</para></listitem>
<listitem><para>Call the function with the right calling convention</para></listitem> <listitem><para>Call the function with the right calling convention.</para></listitem>
<listitem><para>Convert the return values of the C function to python-compatible <listitem><para>Convert the return values of the C function to Python-compatible
variables to return them to the python code.</para></listitem> variables to return them to the Python code.</para></listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
The process described above is pretty complex and there are a lot of ways to make it entirely automatic The process described above is pretty complex and there are a lot of ways to make it entirely automatic
and transparent to the C and the Python programmers: and transparent to C and Python programmers:
<itemizedlist> <itemizedlist>
<listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported, <listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported,
which does the python to C parameter conversion and the C to python return value conversion. This glue code is then which does the Python-to-C parameter conversion and the C-to-Python return value conversion. This glue code is then
linked with the interpreter which allows python programs to call a python functions which delegates the work to the linked with the interpreter which allows Python programs to call Python functions which delegate work to
C function.</para></listitem> C functions.</para></listitem>
<listitem><para>Another nicer solution is to automatically generate the glue code, once for each function exported or <listitem><para>Another, nicer solution is to automatically generate the glue code, once for each function exported or
imported, with a special compiler which imported, with a special compiler which
reads the original function signature.</para></listitem> reads the original function signature.</para></listitem>
<listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of <listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of

View File

@ -30,7 +30,7 @@
Yet another tool that you may find helpful when working with Yet another tool that you may find helpful when working with
GObjects is <ulink GObjects is <ulink
url="http://sourceforge.net/projects/g-inspector">G-Inspector</ulink>. It url="http://sourceforge.net/projects/g-inspector">G-Inspector</ulink>. It
is able to display Glib/Gtk+ objects and their properties. is able to display GLib/GTK+ objects and their properties.
</para> </para>
</chapter> </chapter>
@ -47,8 +47,8 @@
which can be used to automate the task of tracking down the location which can be used to automate the task of tracking down the location
of invalid code with regard to reference counting. This application of invalid code with regard to reference counting. This application
intercepts the reference counting calls and tries to detect invalid behavior. intercepts the reference counting calls and tries to detect invalid behavior.
It suports a filter-rule mechanism to let you trace only the objects you are It supports a filter-rule mechanism to let you trace only the objects you are
interested in and it can be used together with gdb. interested in and it can be used together with GDB.
</para> </para>
<para> <para>
<indexterm><primary>g_trap_object_ref</primary></indexterm> <indexterm><primary>g_trap_object_ref</primary></indexterm>
@ -66,14 +66,14 @@ static volatile GObject *g_trap_object_ref;
<chapter id="tools-gtkdoc"> <chapter id="tools-gtkdoc">
<title>Writing API docs</title> <title>Writing API docs</title>
<para>The API documentation for most of the Glib, GObject, GTK+ and GNOME <para>The API documentation for most of the GLib, GObject, GTK+ and GNOME
libraries is built with a combination of complex tools. Typically, the part of libraries is built with a combination of complex tools. Typically, the part of
the documentation which describes the behavior of each function is extracted the documentation which describes the behavior of each function is extracted
from the specially-formatted source code comments by a tool named gtk-doc which from the specially-formatted source code comments by a tool named gtk-doc which
generates docbook xml and merges this docbook xml with a set of master xml generates DocBook XML and merges this DocBook XML with a set of master XML
docbook files. These xml docbook files are finally processed with xsltproc DocBook files. These XML DocBook files are finally processed with xsltproc
(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> <programlisting>
/** /**
@ -92,9 +92,9 @@ gtk_widget_freeze_child_notify (GtkWidget *widget)
</programlisting> </programlisting>
</para> </para>
<para> <para>
The great thoroughful Thorough
<ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink> <ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink>
on how to setup and use gtk-doc in your on how to set up and use gtk-doc in your
project is provided on the gnome developer website. project is provided on the GNOME developer website.
</para> </para>
</chapter> </chapter>