nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | <?xml version='1.0' encoding="UTF-8"?> |
2 | <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" |
||
3 | "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ |
||
4 | ]> |
||
5 | <chapter id="chapter-intro"> |
||
6 | <title>Background</title> |
||
7 | |||
8 | <para> |
||
9 | GObject, and its lower-level type system, GType, are used by GTK+ and most GNOME libraries to |
||
10 | provide: |
||
11 | <itemizedlist> |
||
12 | <listitem><para>object-oriented C-based APIs and</para></listitem> |
||
13 | <listitem><para>automatic transparent API bindings to other compiled |
||
14 | or interpreted languages.</para></listitem> |
||
15 | </itemizedlist> |
||
16 | </para> |
||
17 | |||
18 | <para> |
||
19 | A lot of programmers are used to working with compiled-only or dynamically interpreted-only |
||
20 | languages and do not understand the challenges associated with cross-language interoperability. |
||
21 | This introduction tries to provide an insight into these challenges and briefly describes |
||
22 | the solution chosen by GLib. |
||
23 | </para> |
||
24 | |||
25 | <para> |
||
26 | The following chapters go into greater detail into how GType and GObject work and |
||
27 | how you can use them as a C programmer. It is useful to keep in mind that |
||
28 | allowing access to C objects from other interpreted languages was one of the major design |
||
29 | goals: this can often explain the sometimes rather convoluted APIs and features present |
||
30 | in this library. |
||
31 | </para> |
||
32 | |||
33 | <sect1> |
||
34 | <title>Data types and programming</title> |
||
35 | |||
36 | <para> |
||
37 | One could say |
||
38 | that a programming language is merely a way to create data types and manipulate them. Most languages |
||
39 | provide a number of language-native types and a few primitives to create more complex types based |
||
40 | on these primitive types. |
||
41 | </para> |
||
42 | |||
43 | <para> |
||
44 | In C, the language provides types such as <emphasis>char</emphasis>, <emphasis>long</emphasis>, |
||
45 | <emphasis>pointer</emphasis>. During compilation of C code, the compiler maps these |
||
46 | language types to the compiler's target architecture machine types. If you are using a C interpreter |
||
47 | (assuming one exists), the interpreter (the program which interprets |
||
48 | the source code and executes it) maps the language types to the machine types of the target machine at |
||
49 | runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine). |
||
50 | </para> |
||
51 | |||
52 | <para> |
||
53 | Perl and Python are interpreted languages which do not really provide type definitions similar |
||
54 | to those used by C. Perl and Python programmers manipulate variables and the type of the variables |
||
55 | is decided only upon the first assignment or upon the first use which forces a type on the variable. |
||
56 | The interpreter also often provides a lot of automatic conversions from one type to the other. For example, |
||
57 | in Perl, a variable which holds an integer can be automatically converted to a string given the |
||
58 | required context: |
||
59 | <informalexample><programlisting> |
||
60 | my $tmp = 10; |
||
61 | print "this is an integer converted to a string:" . $tmp . "\n"; |
||
62 | </programlisting></informalexample> |
||
63 | Of course, it is also often possible to explicitly specify conversions when the default conversions provided |
||
64 | by the language are not intuitive. |
||
65 | </para> |
||
66 | |||
67 | </sect1> |
||
68 | |||
69 | <sect1> |
||
70 | <title>Exporting a C API</title> |
||
71 | |||
72 | <para> |
||
73 | C APIs are defined by a set of functions and global variables which are usually exported from a |
||
74 | binary. C functions have an arbitrary number of arguments and one return value. Each function is thus |
||
75 | uniquely identified by the function name and the set of C types which describe the function arguments |
||
76 | and return value. The global variables exported by the API are similarly identified by their name and |
||
77 | their type. |
||
78 | </para> |
||
79 | |||
80 | <para> |
||
81 | A C API is thus merely defined by a set of names to which a set of types are associated. If you know the |
||
82 | function calling convention and the mapping of the C types to the machine types used by the platform you |
||
83 | are on, you can resolve the name of each function to find where the code associated to this function |
||
84 | is located in memory, and then construct a valid argument list for the function. Finally, all you have to |
||
85 | do is trigger a call to the target C function with the argument list. |
||
86 | </para> |
||
87 | |||
88 | <para> |
||
89 | For the sake of discussion, here is a sample C function and the associated 32 bit x86 |
||
90 | assembly code generated by GCC on a Linux computer: |
||
91 | <informalexample><programlisting> |
||
92 | static void |
||
93 | function_foo (int foo) |
||
94 | { |
||
95 | } |
||
96 | |||
97 | int |
||
98 | main (int argc, |
||
99 | char *argv[]) |
||
100 | { |
||
101 | function_foo (10); |
||
102 | |||
103 | return 0; |
||
104 | } |
||
105 | |||
106 | push $0xa |
||
107 | call 0x80482f4 <function_foo> |
||
108 | </programlisting></informalexample> |
||
109 | The assembly code shown above is pretty straightforward: the first instruction pushes |
||
110 | the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls |
||
111 | <function>function_foo</function>. As you can see, C function calls are implemented by |
||
112 | GCC as native function calls (this is probably the fastest implementation possible). |
||
113 | </para> |
||
114 | |||
115 | <para> |
||
116 | Now, let's say we want to call the C function <function>function_foo</function> from |
||
117 | a Python program. To do this, the Python interpreter needs to: |
||
118 | <itemizedlist> |
||
119 | <listitem><para>Find where the function is located. This probably means finding the binary generated by the C compiler |
||
120 | which exports this function.</para></listitem> |
||
121 | <listitem><para>Load the code of the function in executable memory.</para></listitem> |
||
122 | <listitem><para>Convert the Python parameters to C-compatible parameters before calling |
||
123 | the function.</para></listitem> |
||
124 | <listitem><para>Call the function with the right calling convention.</para></listitem> |
||
125 | <listitem><para>Convert the return values of the C function to Python-compatible |
||
126 | variables to return them to the Python code.</para></listitem> |
||
127 | </itemizedlist> |
||
128 | </para> |
||
129 | |||
130 | <para> |
||
131 | The process described above is pretty complex and there are a lot of ways to make it entirely automatic |
||
132 | and transparent to C and Python programmers: |
||
133 | <itemizedlist> |
||
134 | <listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported, |
||
135 | which does the Python-to-C parameter conversion and the C-to-Python return value conversion. This glue code is then |
||
136 | linked with the interpreter which allows Python programs to call Python functions which delegate work to |
||
137 | C functions.</para></listitem> |
||
138 | <listitem><para>Another, nicer solution is to automatically generate the glue code, once for each function exported or |
||
139 | imported, with a special compiler which |
||
140 | reads the original function signature.</para></listitem> |
||
141 | <listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of |
||
142 | all the objects manipulated by the programmer. This so-called <emphasis>dynamic type</emphasis> |
||
143 | <footnote> |
||
144 | <para> |
||
145 | There are numerous different implementations of dynamic type systems: all C++ |
||
146 | compilers have one, Java and .NET have one too. A dynamic type system allows you |
||
147 | to get information about every instantiated object at runtime. It can be implemented |
||
148 | by a process-specific database: every new object created registers the characteristics |
||
149 | of its associated type in the type system. It can also be implemented by introspection |
||
150 | interfaces. The common point between all these different type systems and implementations |
||
151 | is that they all allow you to query for object metadata at runtime. |
||
152 | </para> |
||
153 | </footnote> |
||
154 | library is then used by special generic glue code to automatically convert function parameters and |
||
155 | function calling conventions between different runtime domains.</para></listitem> |
||
156 | </itemizedlist> |
||
157 | The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain |
||
158 | boundaries is written once: the figure below states this more clearly. |
||
159 | <figure> |
||
160 | <mediaobject> |
||
161 | <imageobject> <!-- this is for HTML output --> |
||
162 | <imagedata fileref="glue.png" format="PNG" align="center"/> |
||
163 | </imageobject> |
||
164 | <imageobject> <!-- this is for PDF output --> |
||
165 | <imagedata fileref="glue.jpg" format="JPG" align="center"/> |
||
166 | </imageobject> |
||
167 | </mediaobject> |
||
168 | </figure> |
||
169 | |||
170 | Currently, there exist at least Python and Perl generic glue code which makes it possible to use |
||
171 | C objects written with GType directly in Python or Perl, with a minimum amount of work: there |
||
172 | is no need to generate huge amounts of glue code either automatically or by hand. |
||
173 | </para> |
||
174 | |||
175 | <para> |
||
176 | Although that goal was arguably laudable, its pursuit has had a major influence on |
||
177 | the whole GType/GObject library. C programmers are likely to be puzzled at the complexity |
||
178 | of the features exposed in the following chapters if they forget that the GType/GObject library |
||
179 | was not only designed to offer OO-like features to C programmers but also transparent |
||
180 | cross-language interoperability. |
||
181 | </para> |
||
182 | |||
183 | </sect1> |
||
184 | |||
185 | </chapter> |