Format XML to be more editable. Describe Interfaces better. Add a footnote

* gobject/tut_gobject.xml:
* gobject/tut_gsignal.xml:
* gobject/tut_gtype.xml:
* gobject/tut_howto.xml:
* gobject/tut_intro.xml:
* gobject/tut_tools.xml:
Format XML to be more editable. Describe Interfaces better. Add a
footnote at first occurance of 'maman_'.

svn path=/trunk/; revision=5334
This commit is contained in:
Stefan Kost 2007-02-10 22:08:42 +00:00
parent bdca945da3
commit 8ec7d6ca3f
7 changed files with 2209 additions and 2193 deletions

View File

@ -1,3 +1,14 @@
2007-02-11 Stefan Kost <ensonic@users.sf.net>
* gobject/tut_gobject.xml:
* gobject/tut_gsignal.xml:
* gobject/tut_gtype.xml:
* gobject/tut_howto.xml:
* gobject/tut_intro.xml:
* gobject/tut_tools.xml:
Format XML to be more editable. Describe Interfaces better. Add a
footnote at first occurance of 'maman_'.
2007-02-08 Stefan Kost <ensonic@users.sf.net> 2007-02-08 Stefan Kost <ensonic@users.sf.net>
* gobject/tut_gobject.xml: * gobject/tut_gobject.xml:

View File

@ -1,5 +1,4 @@
<?xml version='1.0' encoding="ISO-8859-1"?> <?xml version='1.0' encoding="ISO-8859-1"?>
<chapter id="chapter-gobject"> <chapter id="chapter-gobject">
<title>The GObject base class</title> <title>The GObject base class</title>
@ -541,7 +540,6 @@ maman_bar_instance_init (GTypeInstance *instance,
MamanBar *self = (MamanBar *)instance; MamanBar *self = (MamanBar *)instance;
} }
static void static void
maman_bar_set_property (GObject *object, maman_bar_set_property (GObject *object,
guint property_id, guint property_id,
@ -721,7 +719,6 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
<sect2 id="gobject-multi-properties"> <sect2 id="gobject-multi-properties">
<title>Accessing multiple properties at once</title> <title>Accessing multiple properties at once</title>
<para> <para>
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
@ -765,7 +762,6 @@ g_object_set (G_OBJECT (foo),
<!-- @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 classe -->
</sect1> </sect1>
</chapter> </chapter>

View File

@ -48,8 +48,8 @@ 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. callback invocator.</para>
</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
closure invocation, closure invalidation and closure finalization. Listeners closure invocation, closure invalidation and closure finalization. Listeners
@ -64,8 +64,8 @@ return_type function_callback (... , gpointer user_data);
<footnote><para> <footnote><para>
Closures are refcounted and notify listeners of their destruction in a two-stage Closures are refcounted 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></footnote></para>
</para></listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
@ -299,9 +299,6 @@ guint g_signal_newv (const gchar *signal_name,
and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>. and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
</para> </para>
<para>
</para>
</sect2> </sect2>
<sect2 id="signal-emission"> <sect2 id="signal-emission">
@ -501,7 +498,8 @@ void g_signal_emit_by_name (gpointer instance,
(even though they are connected to a signal which is being emitted). (even though they are connected to a signal which is being emitted).
</para> </para>
<para>This completely optional filtering mechanism is mainly used as an optimization for signals <para>
This completely optional filtering mechanism is mainly used as an optimization for signals
which are often emitted for many different reasons: the clients can filter out which events they are which are often emitted for many different reasons: the clients can filter out which events they are
interested into before the closure's marshalling code runs. For example, this is used extensively interested into before the closure's marshalling code runs. For example, this is used extensively
by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject, by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
@ -510,7 +508,8 @@ void g_signal_emit_by_name (gpointer instance,
to only one property to filter most events before receiving them. to only one property to filter most events before receiving them.
</para> </para>
<para>As a simple rule, users can and should set the detail parameter to zero: this will disable completely <para>
As a simple rule, users can and should set the detail parameter to zero: this will disable completely
this optional filtering. this optional filtering.
</para> </para>
@ -518,3 +517,4 @@ void g_signal_emit_by_name (gpointer instance,
</sect1> </sect1>
</chapter> </chapter>

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding="ISO-8859-1"?> <?xml version='1.0' encoding="ISO-8859-1"?>
<chapter> <chapter id="chapter-gtype">
<title>The Glib Dynamic Type System</title> <title>The Glib Dynamic Type System</title>
<para> <para>
@ -236,6 +236,13 @@ struct _GTypeValueTable
</para></listitem> </para></listitem>
<listitem><para>Use prefixing to avoid namespace conflicts with other projects. <listitem><para>Use prefixing to avoid namespace conflicts with other projects.
If your library (or application) is named <emphasis>Maman</emphasis>, If your library (or application) is named <emphasis>Maman</emphasis>,
<footnote>
<para>
<emphasis>Maman</emphasis> is the french word for <emphasis>mum</emphasis>
or <emphasis>mother</emphasis> - nothing more and nothing less.
</para>
</footnote>
prefix all your function names with <emphasis>maman_</emphasis>. prefix all your function names with <emphasis>maman_</emphasis>.
For example: <function>maman_object_method</function>. For example: <function>maman_object_method</function>.
</para></listitem> </para></listitem>
@ -496,6 +503,9 @@ B *b;
</programlisting> </programlisting>
</para> </para>
<sect2 id="gtype-instantiable-classed-init-done">
<title>Initialization and Destruction</title>
<para> <para>
Instanciation of these types can be done with Instanciation 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>:
@ -543,6 +553,7 @@ The class initialization process is entirely implemented in
last living instance of the object, the class is destroyed. last living instance of the object, the class is destroyed.
</para> </para>
<para> <para>
Class destruction Class destruction
<footnote> <footnote>
@ -642,6 +653,8 @@ The class initialization process is entirely implemented in
</table> </table>
</para> </para>
</sect2>
</sect1> </sect1>
<sect1 id="gtype-non-instantiable-classed"> <sect1 id="gtype-non-instantiable-classed">
@ -650,6 +663,9 @@ The class initialization process is entirely implemented in
<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
be seen as a playback interface. Once you know what the do, you can
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 interfacce 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.

View File

@ -1,3 +1,4 @@
<?xml version='1.0' encoding="ISO-8859-1"?>
<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
@ -6,10 +7,6 @@
</para> </para>
</partintro> </partintro>
<!--
Howto GObject
-->
<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>
@ -701,11 +698,13 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
programming idiom is often used, this section attemps to explain how to implement it. programming idiom is often used, this section attemps to explain how to implement it.
</para> </para>
<para>To explicitely chain up to the implementation of the virtual method in the parent class, <para>
To explicitely 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>
<para>The <emphasis>original</emphasis> adjective used in this sentence is not innocuous. To fully <para>
The <emphasis>original</emphasis> adjective used in this sentence is not innocuous. To fully
understand its meaning, you need to recall how class structures are initialized: for each object type, understand its meaning, you need to recall how class structures are initialized: for each object type,
the class structure associated to this object is created by first copying the class structure of its the class structure associated to this object is created by first copying the class structure of its
parent type (a simple <function>memcpy</function>) and then by invoking the class_init callback on parent type (a simple <function>memcpy</function>) and then by invoking the class_init callback on
@ -743,15 +742,8 @@ b_method_to_call (B *obj, int a)
</sect1> </sect1>
</chapter> </chapter>
<!-- End Howto GObject -->
<!--
End Howto GObject
-->
<!--
Howto Interfaces
-->
<chapter id="howto-interface"> <chapter id="howto-interface">
<title>How To define and implement Interfaces?</title> <title>How To define and implement Interfaces?</title>
@ -987,13 +979,15 @@ baz_instance_init (GTypeInstance *instance,
<sect1> <sect1>
<title>Interface definition prerequisites</title> <title>Interface definition prerequisites</title>
<para>To specify that an interface requires the presence of other interfaces when implemented, <para>
To specify that an interface requires the presence of other interfaces when implemented,
GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate
a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface
I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2. I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2.
</para> </para>
<para>The mechanism described above is, in practice, very similar to Java's interface I1 extends <para>
The mechanism described above is, in practice, very similar to Java's interface I1 extends
interface I2. The example below shows the GObject equivalent: interface I2. The example below shows the GObject equivalent:
<programlisting> <programlisting>
@ -1031,7 +1025,6 @@ ibaz_interface_init (gpointer g_iface,
iface->do_action = (void (*) (MamanIbaz *self))ibaz_do_action; iface->do_action = (void (*) (MamanIbaz *self))ibaz_do_action;
} }
static void static void
bar_instance_init (GTypeInstance *instance, bar_instance_init (GTypeInstance *instance,
gpointer g_class) gpointer g_class)
@ -1040,7 +1033,6 @@ bar_instance_init (GTypeInstance *instance,
self->instance_member = 0x666; self->instance_member = 0x666;
} }
GType GType
maman_bar_get_type (void) maman_bar_get_type (void)
{ {
@ -1096,14 +1088,16 @@ maman_bar_get_type (void)
<sect1 id="howto-interface-properties"> <sect1 id="howto-interface-properties">
<title>Interface Properties</title> <title>Interface Properties</title>
<para>Starting from version 2.4 of glib, GObject interfaces can also have properties. <para>
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
declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>. declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
</para> </para>
<para>To include a property named 'name' of type <type>string</type> in the <para>
To include a property named 'name' of type <type>string</type> in the
<type>maman_ibaz</type> interface example code above, we only need to add one <type>maman_ibaz</type> interface example code above, we only need to add one
<footnote> <footnote>
<para> <para>
@ -1139,13 +1133,15 @@ maman_ibaz_base_init (gpointer g_iface)
</programlisting> </programlisting>
</para> </para>
<para>One point worth noting is that the declared property wasn't assigned an <para>
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 properities 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>
<para>The story for the implementers of the interface is also quite trivial. <para>
The story for the implementers of the interface is also quite trivial.
An implementer shall declare and define it's properties in the usual way as An implementer shall declare and define it's properties in the usual way as
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
@ -1260,19 +1256,8 @@ maman_baz_get_property (GObject * object, guint prop_id,
</para> </para>
</sect1> </sect1>
</chapter> </chapter>
<!-- End Howto Interfaces -->
<!--
End Howto Interfaces
-->
<!--
start Howto Signals
-->
<chapter id="howto-signals"> <chapter id="howto-signals">
<title>Howto create and use signals</title> <title>Howto create and use signals</title>
@ -1294,7 +1279,8 @@ maman_baz_get_property (GObject * object, guint prop_id,
<sect1 id="howto-simple-signals"> <sect1 id="howto-simple-signals">
<title>Simple use of signals</title> <title>Simple use of signals</title>
<para>The most basic use of signals is to implement simple event notification: for example, if we have a <para>
The most basic use of signals is to implement simple event notification: for example, if we have a
MamanFile object, and if this object has a write method, we might wish to be notified whenever someone MamanFile object, and if this object has a write method, we might wish to be notified whenever someone
uses this method. The code below shows how the user can connect a callback to the write signal. Full code uses this method. The code below shows how the user can connect a callback to the write signal. Full code
for this simple example is located in <filename>sample/signal/maman-file.{h|c}</filename> and for this simple example is located in <filename>sample/signal/maman-file.{h|c}</filename> and
@ -1350,25 +1336,26 @@ 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
needed closures that one can use. needed closures that one can use.
</para> </para>
</sect1> </sect1>
<sect1> <sect1>
<title>How to provide more flexibility to users?</title> <title>How to provide more flexibility to users?</title>
<para>The previous implementation does the job but the signal facility of GObject can be used to provide <para>
The previous implementation does the job but the signal facility of GObject can be used to provide
even more flexibility to this file change notification mechanism. One of the key ideas is to make the process even more flexibility to this file change notification mechanism. One of the key ideas is to make the process
of writing data to the file part of the signal emission process to allow users to be notified either of writing data to the file part of the signal emission process to allow users to be notified either
before or after the data is written to the file. before or after the data is written to the file.
</para> </para>
<para>To integrate the process of writing the data to the file into the signal emission mechanism, we can <para>
To integrate the process of writing the data to the file into the signal emission mechanism, we can
register a default class closure for this signal which will be invoked during the signal emission, just like register a default class closure for this signal which will be invoked during the signal emission, just like
any other user-connected signal handler. any other user-connected signal handler.
</para> </para>
<para>The first step to implement this idea is to change the signature of the signal: we need to pass <para>
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:
@ -1380,7 +1367,8 @@ and use the Makefile provided in <filename>sample/signal/Makefile</filename> to
<filename>maman-file-complex.c</filename>. <filename>maman-file-complex.c</filename>.
</para> </para>
<para>Once the marshaller is present, we register the signal and its marshaller in the class_init function <para>
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> <programlisting>
@ -1423,7 +1411,8 @@ default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer
</programlisting> </programlisting>
</para> </para>
<para>Finally, the client code must invoke the <function>maman_file_complex_write</function> function which <para>
Finally, the client code must invoke the <function>maman_file_complex_write</function> function which
triggers the signal emission: triggers the signal emission:
<programlisting> <programlisting>
void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size) void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
@ -1437,7 +1426,8 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
</programlisting> </programlisting>
</para> </para>
<para>The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect signal handlers before <para>
The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect signal handlers before
and after the file write is completed: since the default signal handler which does the write itself runs during the and after the file write is completed: since the default signal handler which does the write itself runs during the
RUN_LAST phase of the signal emission, it will run after all handlers connected with <function><link linkend="g-signal-connect">g_signal_connect</link></function> RUN_LAST phase of the signal emission, it will run after all handlers connected with <function><link linkend="g-signal-connect">g_signal_connect</link></function>
and before all handlers connected with <function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function>. If you intent to write a GObject and before all handlers connected with <function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function>. If you intent to write a GObject
@ -1592,11 +1582,9 @@ klass->write_signal_id =
</sect2> </sect2>
</sect1> </sect1>
<sect1> <sect1>
<title>How users can abuse signals (and why some think it is good)</title> <title>How users can abuse signals (and why some think it is good)</title>
@ -1607,7 +1595,8 @@ klass->write_signal_id =
This will make you feel good and eleet. This will make you feel good and eleet.
</para> </para>
<para>The users can: <para>
The users can:
<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
@ -1616,28 +1605,32 @@ klass->write_signal_id =
</itemizedlist> </itemizedlist>
</para> </para>
<para>In both cases, the original programmer should be as careful as possible to write code which is <para>
In both cases, the original programmer should be as careful as possible to write code which is
resistant to the fact that the default handler of the signal might not able to run. This is obviously resistant to the fact that the default handler of the signal might not able to run. This is obviously
not the case in the example used in the previous sections since the write to the file depends on whether not the case in the example used in the previous sections since the write to the file depends on whether
or not the default handler runs (however, this might be your goal: to allow the user to prevent the file or not the default handler runs (however, this might be your goal: to allow the user to prevent the file
write if he wishes to). write if he wishes to).
</para> </para>
<para>If all you want to do is to stop the signal emission from one of the callbacks you connected yourself, <para>
If all you want to do is to stop the signal emission from one of the callbacks you connected yourself,
you can call <function><link linkend="g-signal-stop-by-name">g_signal_stop_by_name</link></function>. Its use is very simple which is why I won't detail you can call <function><link linkend="g-signal-stop-by-name">g_signal_stop_by_name</link></function>. Its use is very simple which is why I won't detail
it further. it further.
</para> </para>
<para>If the signal's default handler is just a class function pointer, it is also possible to override <para>
If the signal's default handler is just a class function pointer, it is also possible to override
it yourself from the class_init function of a type which derives from the parent. That way, when the signal it yourself from the class_init function of a type which derives from the parent. That way, when the signal
is emitted, the parent class will use the function provided by the child as a signal default handler. is emitted, the parent class will use the function provided by the child as a signal default handler.
Of course, it is also possible (and recommended) to chain up from the child to the parent's default signal Of course, it is also possible (and recommended) to chain up from the child to the parent's default signal
handler to ensure the integrity of the parent object. handler to ensure the integrity of the parent object.
</para> </para>
<para>Overriding a class method and chaining up was demonstrated in <xref linkend="howto-gobject-methods"/> <para>
which is why I won't bother to show exactly how to do it here again.</para> Overriding a class method and chaining up was demonstrated in <xref linkend="howto-gobject-methods"/>
which is why I won't bother to show exactly how to do it here again.
</para>
</sect1> </sect1>
@ -1723,10 +1716,3 @@ g_object_do_class_init (GObjectClass *class)
</sect2> </sect2>
--> -->
<!--
<capter1 id="howto-doc">
<title>How to generate API documentation for your type?</title>
</chapter>
-->

View File

@ -1,4 +1,5 @@
<chapter> <?xml version='1.0' encoding="ISO-8859-1"?>
<chapter id="chapter-intro">
<title>Background</title> <title>Background</title>
<para> <para>
@ -11,13 +12,15 @@ or interpreted languages.</para></listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para>A lot of programmers are used to work with compiled-only or dynamically interpreted-only <para>
A lot of programmers are used to work 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. describes briefly
the solution choosen by GLib. the solution choosen by GLib.
</para> </para>
<para>The following chapters go into greater detail into how GType and GObject work and <para>
The following chapters go into greater detail into how GType and GObject work and
how you can use them as a C programmer. It is useful to keep in mind that how you can use them as a C programmer. It is useful to keep in mind that
allowing access to C objects from other interpreted languages was one of the major design allowing access to C objects from other interpreted languages was one of the major design
goals: this can often explain the sometimes rather convoluted APIs and features present goals: this can often explain the sometimes rather convoluted APIs and features present
@ -43,7 +46,8 @@ the source code and executes it) maps the language types to the machine types of
runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine). runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine).
</para> </para>
<para>Perl and Python which are interpreted languages do not really provide type definitions similar <para>
Perl and Python which are interpreted languages 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,
@ -62,7 +66,8 @@ by the language are not intuitive.
<sect1> <sect1>
<title>Exporting a C API</title> <title>Exporting a C API</title>
<para>C APIs are defined by a set of functions and global variables which are usually exported from a <para>
C APIs are defined by a set of functions and global variables which are usually exported from a
binary. C functions have an arbitrary number of arguments and one return value. Each function is thus binary. C functions have an arbitrary number of arguments and one return value. Each function is thus
uniquely identified by the function name and the set of C types which describe the function arguments uniquely identified by the function name and the set of C types which describe the function arguments
and return value. The global variables exported by the API are similarly identified by their name and and return value. The global variables exported by the API are similarly identified by their name and
@ -116,7 +121,8 @@ variables to return them to the python code.</para></listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para>The process described above is pretty complex and there are a lot of ways to make it entirely automatic <para>
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 the C and the 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,
@ -127,7 +133,8 @@ C function.</para></listitem>
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
all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis><footnote> all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis>
<footnote>
<para> <para>
There are numerous different implementations of dynamic type systems: all C++ There are numerous different implementations of dynamic type systems: all C++
compilers have one, Java and .NET have one too. A dynamic type system allows you compilers have one, Java and .NET have one too. A dynamic type system allows you
@ -138,10 +145,8 @@ all the objects manipulated by the programmer. This so-called <emphasis>dynamic
is that they all allow you to query for object metadata at runtime. is that they all allow you to query for object metadata at runtime.
</para> </para>
</footnote> </footnote>
library is then used by special generic glue code to automatically convert function parameters and
library is then function calling conventions between different runtime domains.</para></listitem>
used by special generic glue code to automatically convert function parameters and function calling conventions
between different runtime domains.</para></listitem>
</itemizedlist> </itemizedlist>
The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain
boundaries is written once: the figure below states this more clearly. boundaries is written once: the figure below states this more clearly.
@ -161,7 +166,8 @@ C objects written with GType directly in Python or Perl, with a minimum amount o
is no need to generate huge amounts of glue code either automatically or by hand. is no need to generate huge amounts of glue code either automatically or by hand.
</para> </para>
<para>Although that goal was arguably laudable, its pursuit has had a major influence on <para>
Although that goal was arguably laudable, its pursuit has had a major influence on
the whole GType/GObject library. C programmers are likely to be puzzled at the complexity the whole GType/GObject library. C programmers are likely to be puzzled at the complexity
of the features exposed in the following chapters if they forget that the GType/GObject library of the features exposed in the following chapters if they forget that the GType/GObject library
was not only designed to offer OO-like features to C programmers but also transparent was not only designed to offer OO-like features to C programmers but also transparent

View File

@ -1,3 +1,4 @@
<?xml version='1.0' encoding="ISO-8859-1"?>
<partintro> <partintro>
<para> <para>
Several useful developer tools have been build around GObject technology. Several useful developer tools have been build around GObject technology.