Skip to content

Wrapping pygtk widgets – what you should know

31/07/2009

In past days I’ve encountered a series of problems. In this article I will explain what kind of problem one can found and how to solve this problems.

I’ve some hints:

  • Study the C syntax and the pointers , skip all the algorithmic part: it’s not useful for wrapping a python module.
  • It’s useful to  study some C++  for design purposes, the C manuals doesn’t face well the multiple-file programs, compilation,  headers topics… In C++ this is necessary and well explained in manuals.
  • The most important thing you should know is how to read (and write ) simple Makefiles,  I’ve tried to learn autotools but they are very hard to understand.

Libraries and python modules

A python module (from a C wrapper)  is a shared library. What’s shared, and what’s library? Let’s explain with a simple example.

Suppose you are a mathematician and you’ve coded in C your ugly formulas.  You want to use this formulas in other programs.

The best solution is to split your program in three files:

  • main.c : Run the program, using the functions you specify in other files.( includes headers files like ugly-functions.h to define the fuctions prototypes)
  • ugly-functions.h : here are the function prototipes, each function is declared and explained in an human-readable format ( a lot of  comments)
  • ugly-functions.c : here are the function implementations, you code what each function do.

Well, it’s time to compile your boring program. You can compile with:

gcc ugly-functions.c main.c -o boring-program

Another way, more interesting:

gcc -c ugly-functions.c # The output is a file called ugly-functions.o
gcc -c main.c           # main.o
gcc main.o ugly.functions.o -o boring-program # This phase is called linking

With the first two commands you create object files.  With the last command you link the so called object-files in an executable form.

The -c option tells gcc to don’t call the linker. The linker links the function implementations to their name. (otherwise main.c couldn’t find the function implementations).

Static libraries

Now you can found other formulas and code them in another file:  good-formulas.c.

You make your header file(.h), and your source file (.c), now you can compile with the same command.

gcc -c ugly-functions.c # The output is a file called ugly-functions.o
gcc -c good-formulas.c  # good-formulas.o
gcc -c main.c           # main.o
gcc main.o ugly.functions.o good-formulas.o -o interesting-program

Ok you have obtained your interesting program with your new good formulas.  Now you may want to transform them in libraries.

Static libraries

To make a static library, you can group (archive) your object-files in a single file with this command:


ar rcs libmine.a ugly-functions.o good-formulas.o


now with this archive you can link your functions to the main program in this way:

gcc main.o libmine.a -o interesting-program

OK. You’ve done our static library. You’ve copied in the final executable all the object-files.  When there are a lot of object-files the executable will growth in dimension. Here comes the shared libraries.

A note before proceeding, static libraries are discouraged in general.

Shared libraries

Now there’s the most important part of the tutorial.  Because python modules are shared libraries.

To make a shared library, you have to recompile your .c files in a special manner, with the -fPIC option:  this makes the library to be loaded and referenced at run time.

gcc -c -fPIC ugly-functions.c
gcc -c -fPIC good-formulas.c

Now we can create the library, libmine.so :

gcc -shared ugly-functions.o good-formulas.o -o libmine.so

Now it’s time to link, you can use the same method:

gcc main.o libmine.so -o interesting-program

There’s another way to link the program, that is mostly used:

gcc -L/directory/containing/library -lmine main.o -o interesting-program

The -l option specifies which library to link when you use this you have to omit the lib prefix and the .so suffix  (if there isn’t the lib prefix you have to omit only the .so suffix).

The -L option specifies the path where to find the library.

Remember this options that are widely used in Makefiles.

Now this library can be used by a lot of programs and it’s linked at runtime but it has to be reachable. If you run the program you will catch this error:

./interesting-program: error while loading shared libraries: libmine.so:
 cannot open shared object file: No such file or directory

You have to tell to the system where to find the library, you can put it in a standard location like /usr/lib or you can use the variable LD_LIBRARY_PATH.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/directory/containing/library

Re-run and it should be ok. There are a lot of other problems you can encounter, mostly related to the file you have linked in the library.

What you should take at home

When you compile python module in a shared library you can encounter a lot of problems:

  • Sure you that you have compiled ALL the object files with the -fPIC option
  • You must include all the libraries that contains the functions defined. Otherwise you will encounter “undefined symbol” errors.
  • Others that now I can’t remember

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: