| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  | <?xml version='1.0' encoding="ISO-8859-1"?> | 
					
						
							| 
									
										
										
										
											2010-01-07 10:47:20 +02:00
										 |  |  | <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"  | 
					
						
							|  |  |  |                "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ | 
					
						
							|  |  |  | ]> | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  | <chapter id="chapter-intro"> | 
					
						
							|  |  |  |   <title>Background</title> | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   <para> | 
					
						
							|  |  |  |     GObject, and its lower-level type system, GType, are used by GTK+ and most GNOME libraries to | 
					
						
							|  |  |  |     provide: | 
					
						
							|  |  |  |     <itemizedlist> | 
					
						
							|  |  |  |       <listitem><para>object-oriented C-based APIs and</para></listitem> | 
					
						
							|  |  |  |       <listitem><para>automatic transparent API bindings to other compiled  | 
					
						
							|  |  |  |       or interpreted languages.</para></listitem> | 
					
						
							|  |  |  |     </itemizedlist> | 
					
						
							|  |  |  |   </para> | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   <para> | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |     A lot of programmers are used to working with compiled-only or dynamically interpreted-only | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |     languages and do not understand the challenges associated with cross-language interoperability. | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |     This introduction tries to provide an insight into these challenges and briefly describes | 
					
						
							|  |  |  |     the solution chosen by GLib. | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |   </para> | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   <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 | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  |     in this library. | 
					
						
							|  |  |  |   </para> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <sect1> | 
					
						
							|  |  |  |     <title>Data types and programming</title> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							|  |  |  |       One could say (I have seen such definitions used in some textbooks on programming language theory) | 
					
						
							|  |  |  |       that a programming language is merely a way to create data types and manipulate them. Most languages | 
					
						
							|  |  |  |       provide a number of language-native types and a few primitives to create more complex types based | 
					
						
							|  |  |  |       on these primitive types. | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							|  |  |  |       In C, the language provides types such as <emphasis>char</emphasis>, <emphasis>long</emphasis>,  | 
					
						
							|  |  |  |       <emphasis>pointer</emphasis>. During compilation of C code, the compiler maps these | 
					
						
							|  |  |  |       language types to the compiler's target architecture machine types. If you are using a C interpreter | 
					
						
							|  |  |  |       (I have never seen one myself but it is possible :), the interpreter (the program which interprets  | 
					
						
							|  |  |  |       the source code and executes it) maps the language types to the machine types of the target machine at  | 
					
						
							|  |  |  |       runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine). | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       Perl and Python are interpreted languages which do not really provide type definitions similar | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       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. | 
					
						
							|  |  |  |       The interpreter also often provides a lot of automatic conversions from one type to the other. For example, | 
					
						
							|  |  |  |       in Perl, a variable which holds an integer can be automatically converted to a string given the | 
					
						
							|  |  |  |       required context: | 
					
						
							| 
									
										
										
										
											2004-01-22 18:39:45 +00:00
										 |  |  | <programlisting> | 
					
						
							|  |  |  | my $tmp = 10; | 
					
						
							|  |  |  | print "this is an integer converted to a string:" . $tmp . "\n"; | 
					
						
							|  |  |  | </programlisting> | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       Of course, it is also often possible to explicitly specify conversions when the default conversions provided | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       by the language are not intuitive. | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |   </sect1> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <sect1> | 
					
						
							|  |  |  |     <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  | 
					
						
							|  |  |  |       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 | 
					
						
							|  |  |  |       and return value. The global variables exported by the API are similarly identified by their name and  | 
					
						
							|  |  |  |       their type. | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							|  |  |  |       A C API is thus merely defined by a set of names to which a set of types are associated. If you know the | 
					
						
							|  |  |  |       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  | 
					
						
							|  |  |  |       is located in memory, and then construct a valid argument list for the function. Finally, all you have to  | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       do is trigger a call to the target C function with the argument list. | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							|  |  |  |       For the sake of discussion, here is a sample C function and the associated 32 bit x86  | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       assembly code generated by GCC on my Linux box: | 
					
						
							| 
									
										
										
										
											2004-01-22 18:39:45 +00:00
										 |  |  | <programlisting> | 
					
						
							|  |  |  | static void function_foo (int foo) | 
					
						
							|  |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main (int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function_foo (10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | push   $0xa | 
					
						
							|  |  |  | call   0x80482f4 <function_foo> | 
					
						
							|  |  |  | </programlisting> | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       The assembly code shown above is pretty straightforward: the first instruction pushes | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls  | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       <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). | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							|  |  |  |       Now, let's say we want to call the C function <function>function_foo</function> from  | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       a Python program. To do this, the Python interpreter needs to: | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       <itemizedlist> | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |         <listitem><para>Find where the function is located. This probably means finding the binary generated by the C compiler | 
					
						
							|  |  |  |         which exports this function.</para></listitem> | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |         <listitem><para>Load the code of the function in executable memory.</para></listitem> | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |         <listitem><para>Convert the Python parameters to C-compatible parameters before calling  | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |         the function.</para></listitem> | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |         <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 | 
					
						
							|  |  |  |         variables to return them to the Python code.</para></listitem> | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       </itemizedlist> | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <para> | 
					
						
							|  |  |  |       The process described above is pretty complex and there are a lot of ways to make it entirely automatic | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |       and transparent to C and Python programmers: | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |       <itemizedlist> | 
					
						
							|  |  |  |         <listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported, | 
					
						
							| 
									
										
										
										
											2007-11-13 07:10:42 +00:00
										 |  |  |         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 Python functions which delegate work to | 
					
						
							|  |  |  |         C functions.</para></listitem> | 
					
						
							|  |  |  |         <listitem><para>Another, nicer solution is to automatically generate the glue code, once for each function exported or | 
					
						
							| 
									
										
										
										
											2007-02-10 22:08:42 +00:00
										 |  |  |         imported, with a special compiler which | 
					
						
							|  |  |  |         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 | 
					
						
							|  |  |  |         all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis> | 
					
						
							|  |  |  |         <footnote> | 
					
						
							|  |  |  |           <para> | 
					
						
							|  |  |  |             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 | 
					
						
							|  |  |  |             to get information about every instantiated object at runtime. It can be implemented | 
					
						
							|  |  |  |             by a process-specific database: every new object created registers the characteristics  | 
					
						
							|  |  |  |             of its associated type in the type system. It can also be implemented by introspection | 
					
						
							|  |  |  |             interfaces. The common point between all these different type systems and implementations | 
					
						
							|  |  |  |             is that they all allow you to query for object metadata at runtime. | 
					
						
							|  |  |  |           </para> | 
					
						
							|  |  |  |         </footnote> | 
					
						
							|  |  |  |         library is then used by special generic glue code to automatically convert function parameters and | 
					
						
							|  |  |  |         function calling conventions between different runtime domains.</para></listitem> | 
					
						
							|  |  |  |       </itemizedlist> | 
					
						
							|  |  |  |       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. | 
					
						
							|  |  |  |       <figure> | 
					
						
							|  |  |  |         <mediaobject> | 
					
						
							|  |  |  |           <imageobject> <!-- this is for HTML output --> | 
					
						
							|  |  |  |             <imagedata fileref="glue.png" format="PNG" align="center"/> | 
					
						
							|  |  |  |           </imageobject> | 
					
						
							|  |  |  |           <imageobject> <!-- this is for PDF output --> | 
					
						
							|  |  |  |             <imagedata fileref="glue.jpg" format="JPG" align="center"/> | 
					
						
							|  |  |  |           </imageobject> | 
					
						
							|  |  |  |         </mediaobject> | 
					
						
							|  |  |  |       </figure> | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       Currently, there exist at least Python and Perl generic glue code which makes it possible to use | 
					
						
							|  |  |  |       C objects written with GType directly in Python or Perl, with a minimum amount of work: there | 
					
						
							|  |  |  |       is no need to generate huge amounts of glue code either automatically or by hand. | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     <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  | 
					
						
							|  |  |  |       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  | 
					
						
							|  |  |  |       cross-language interoperability. | 
					
						
							|  |  |  |     </para> | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   </sect1> | 
					
						
							| 
									
										
										
										
											2004-01-22 18:39:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | </chapter> |