Blame docs/reference/gobject/html/ch01s02.html

Packit ae235b
Packit ae235b
<html>
Packit ae235b
<head>
Packit ae235b
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Packit ae235b
<title>Exporting a C API: GObject Reference Manual</title>
Packit ae235b
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
Packit ae235b
<link rel="home" href="index.html" title="GObject Reference Manual">
Packit ae235b
<link rel="up" href="chapter-intro.html" title="Background">
Packit ae235b
<link rel="prev" href="chapter-intro.html" title="Background">
Packit ae235b
<link rel="next" href="chapter-gtype.html" title="The GLib Dynamic Type System">
Packit ae235b
<meta name="generator" content="GTK-Doc V1.27 (XML mode)">
Packit ae235b
<link rel="stylesheet" href="style.css" type="text/css">
Packit ae235b
</head>
Packit ae235b
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
Packit ae235b
Packit ae235b
Packit ae235b
Home
Packit ae235b
Up
Packit ae235b
Prev
Packit ae235b
Next
Packit ae235b
Packit ae235b
Packit ae235b

Packit ae235b
Exporting a C API
Packit ae235b

Packit ae235b
      C APIs are defined by a set of functions and global variables which are usually exported from a 
Packit ae235b
      binary. C functions have an arbitrary number of arguments and one return value. Each function is thus
Packit ae235b
      uniquely identified by the function name and the set of C types which describe the function arguments
Packit ae235b
      and return value. The global variables exported by the API are similarly identified by their name and 
Packit ae235b
      their type.
Packit ae235b
    

Packit ae235b

Packit ae235b
      A C API is thus merely defined by a set of names to which a set of types are associated. If you know the
Packit ae235b
      function calling convention and the mapping of the C types to the machine types used by the platform you 
Packit ae235b
      are on, you can resolve the name of each function to find where the code associated to this function 
Packit ae235b
      is located in memory, and then construct a valid argument list for the function. Finally, all you have to 
Packit ae235b
      do is trigger a call to the target C function with the argument list.
Packit ae235b
    

Packit ae235b

Packit ae235b
      For the sake of discussion, here is a sample C function and the associated 32 bit x86 
Packit ae235b
      assembly code generated by GCC on a Linux computer:
Packit ae235b

Packit ae235b
Packit ae235b
  
Packit ae235b
    
Packit ae235b
      
Packit ae235b
        
1
Packit ae235b
2
Packit ae235b
3
Packit ae235b
4
Packit ae235b
5
Packit ae235b
6
Packit ae235b
7
Packit ae235b
8
Packit ae235b
9
Packit ae235b
10
Packit ae235b
11
Packit ae235b
12
Packit ae235b
13
Packit ae235b
14
Packit ae235b
15
Packit ae235b
16
Packit ae235b
        
static void
Packit ae235b
function_foo (int foo)
Packit ae235b
{
Packit ae235b
}
Packit ae235b
Packit ae235b
int
Packit ae235b
main (int   argc,
Packit ae235b
      char *argv[])
Packit ae235b
{
Packit ae235b
    function_foo (10);
Packit ae235b
Packit ae235b
    return 0;
Packit ae235b
}
Packit ae235b
Packit ae235b
push   $0xa
Packit ae235b
call   0x80482f4 <function_foo>
Packit ae235b
      
Packit ae235b
    
Packit ae235b
  
Packit ae235b
Packit ae235b
Packit ae235b

Packit ae235b
      The assembly code shown above is pretty straightforward: the first instruction pushes
Packit ae235b
      the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls 
Packit ae235b
      function_foo. As you can see, C function calls are implemented by
Packit ae235b
      GCC as native function calls (this is probably the fastest implementation possible).
Packit ae235b
    

Packit ae235b

Packit ae235b
      Now, let's say we want to call the C function function_foo from 
Packit ae235b
      a Python program. To do this, the Python interpreter needs to:
Packit ae235b
      

Packit ae235b
    Packit ae235b
  • Find where the function is located. This probably means finding the binary generated by the C compiler

  • Packit ae235b
            which exports this function.

    Packit ae235b
  • Load the code of the function in executable memory.

  • Packit ae235b
  • Convert the Python parameters to C-compatible parameters before calling

  • Packit ae235b
            the function.

    Packit ae235b
  • Call the function with the right calling convention.

  • Packit ae235b
  • Convert the return values of the C function to Python-compatible

  • Packit ae235b
            variables to return them to the Python code.

    Packit ae235b
    Packit ae235b

    Packit ae235b
        

    Packit ae235b

    Packit ae235b
          The process described above is pretty complex and there are a lot of ways to make it entirely automatic
    Packit ae235b
          and transparent to C and Python programmers:
    Packit ae235b
          

    Packit ae235b
      Packit ae235b
    • The first solution is to write by hand a lot of glue code, once for each function exported or imported,

    • Packit ae235b
              which does the Python-to-C parameter conversion and the C-to-Python return value conversion. This glue code is then 
      Packit ae235b
              linked with the interpreter which allows Python programs to call Python functions which delegate work to
      Packit ae235b
              C functions.

      Packit ae235b
    • Another, nicer solution is to automatically generate the glue code, once for each function exported or

    • Packit ae235b
              imported, with a special compiler which
      Packit ae235b
              reads the original function signature.

      Packit ae235b
    • The solution used by GLib is to use the GType library which holds at runtime a description of

    • Packit ae235b
              all the objects manipulated by the programmer. This so-called dynamic type
      Packit ae235b
              <sup class="footnote">[1]</sup>
      Packit ae235b
              library is then used by special generic glue code to automatically convert function parameters and
      Packit ae235b
              function calling conventions between different runtime domains.

      Packit ae235b
      Packit ae235b

      Packit ae235b
            The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain 
      Packit ae235b
            boundaries is written once: the figure below states this more clearly.
      Packit ae235b
            

      Packit ae235b
      Packit ae235b

      Figure 1. 

      Packit ae235b
      Packit ae235b
      Packit ae235b


      Packit ae235b
            
      Packit ae235b
            Currently, there exist at least Python and Perl generic glue code which makes it possible to use
      Packit ae235b
            C objects written with GType directly in Python or Perl, with a minimum amount of work: there
      Packit ae235b
            is no need to generate huge amounts of glue code either automatically or by hand.
      Packit ae235b
          

      Packit ae235b

      Packit ae235b
            Although that goal was arguably laudable, its pursuit has had a major influence on
      Packit ae235b
            the whole GType/GObject library. C programmers are likely to be puzzled at the complexity 
      Packit ae235b
            of the features exposed in the following chapters if they forget that the GType/GObject library
      Packit ae235b
            was not only designed to offer OO-like features to C programmers but also transparent 
      Packit ae235b
            cross-language interoperability.
      Packit ae235b
          

      Packit ae235b
      Packit ae235b


      Packit ae235b
      Packit ae235b
                  There are numerous different implementations of dynamic type systems: all C++ 
      Packit ae235b
                  compilers have one, Java and .NET have one too. A dynamic type system allows you
      Packit ae235b
                  to get information about every instantiated object at runtime. It can be implemented
      Packit ae235b
                  by a process-specific database: every new object created registers the characteristics 
      Packit ae235b
                  of its associated type in the type system. It can also be implemented by introspection
      Packit ae235b
                  interfaces. The common point between all these different type systems and implementations
      Packit ae235b
                  is that they all allow you to query for object metadata at runtime.
      Packit ae235b
                

      Packit ae235b
      Packit ae235b
      Packit ae235b
      Packit ae235b

      Generated by GTK-Doc V1.27
      Packit ae235b
      </body>
      Packit ae235b
      </html>