Writing Python bindings of existing C libraries – (2) – A simple example of binding

Posted on Thu 06 August 2009 in HowTo, Igalia, Linux, Maemo (EN), Programmazione, Python • Tagged with binding, Igalia, maemo, Python

Introduction

As I promised in the preceding post, I'll provide a very easy example of a python binding. Let's suppose we don't want to use the methods included in Python to sum two integer values and we want to do it in C and then call the add method from a python script. I'll write the complete source code first and then I'll explain all the parts of it.

Source Code

#include <Python.h>

static PyObject *foo_add(PyObject *self, PyObject *args)  
{  
    int a;  
    int b;

    if (!PyArg_ParseTuple(args, "ii", &a, &b))  
    {  
        return NULL;  
    }

    return Py_BuildValue("i", a + b);  
}

static PyMethodDef foo_methods[] = {  
    { "add", (PyCFunction)foo_add, METH_VARARGS, NULL },  
    { NULL, NULL, 0, NULL }  
};

PyMODINIT_FUNC initfoo()
{  
    Py_InitModule3("foo", foo_methods, "My first extension module.");  
}

How it works

First of all we have to include Python.h in our C file. This allows us to write an extension for Python language. To be able to include this header, we must have the python development packages installed in our system. For example in Debian based distributions we can install them with this command:

sudo apt-get install python2.5-dev

Every module has at least three parts. In the first part we write methods we want to call from the final python module: in this case we have a method called foo_add where "foo" is the name of the module and "add" the name of the method. Every method is declared as static PyObject. The method does anything particular except calling PyArg_ParseTuple to validate the input (we'll discuss this later), adding the two passed numbers and returning the result.

In the second part we have something like a dictionary, defined as static PyMethodDef and called foo_methods (where "foo" again is the name of the module). For each method we want to expose in our python module, we have to add something like this:

{"add", (PyCFunction)foo_add, METH_VARARGS, NULL}

where "add" is the name of the method we want to be visible in our module, (PyCFunction)foo_add is a pointer to our foo_add method, implemented in the C module, METH_VARARGS means that we want to pass some parameters to the function and the last one would be the description of the method (we can leave it NULL if we want).

Third part allows us to register the defined method/s and the module:

Py_InitModule3("foo", foo_methods, "My first extension module.");

Parsing Parameters

The PyArg_ParseTuple function extracts arguments from the PyObject passed as parameter to the current method and follows almost the sscanf syntax to parse parameters (in this case we had "ii" for two integers). You can fin the complete reference here: http://docs.python.org/c-api/arg.html

Building and installing

To build the module, we have to be in the source directory and execute this command:

gcc -shared -I/usr/include/python2.5 foo.c -o foo.so

then we've to copy the generated module to the python's modules directory:

cp foo.so /usr/lib/python2.5/site-packages/

Testing our module

Testing the module is really easy. We've to start a python shell or create a python script with the following source code:

import foo
print foo.add(2, 3)

if all is working fine, the printed result should be 5

References


Writing Python bindings of existing C libraries - (1) - Introduction

Posted on Mon 03 August 2009 in HowTo, Igalia, Linux, Maemo (EN), Programmazione, Python • Tagged with bindings, C, Igalia, libraries, library, maemo, pymaemo, Python

This summer I'm having the pleasure of working in Igalia (a spanish free software company) for a couple of months and they assigned me to an interesting project: developing Python bindings for MAFW library (a Maemo multimedia library that will be used in Fremantle release).

Having the opportunity to work both with C (yes, Python bindings are almost C code) and Python (it's a good practice to write unittest of all implemented methods) it's a good way to improve my knowledges in both languages and since I wasn't able to find much documentation about these kind of things, I'm going to share my own experiences.

What is a Binding?

A binding is a Python module, written in C language, that allows Python developers to call functions from existing C libraries from their python applications. It's just like a "bridge" from C world to Python one.

Why writing bindings?

There are a couple of reasons to write python bindings instead of writing a library in python language from scratch.

First of all I don't think is good duplicating code, so if a library already exists and it's written in C, why writing it again in another language? There's no reason. A lot of code already exist in C world and all we have to do is to create a bridge with python world.

Another good reason, in particular when a C library doesn't exist yet, is the fact that python code is slower than C code for some tasks (for example multimedia codecs). In these cases is good to implement the core library in C language and then create a python binding for it.

Coming next

As the title of this post says, this is only an introduction to the subjects I'm going to write about. If you have any particular request about any argument you would like to read, please feel free to leave me a comment. Next posts will talk about these things:

  • A simple example of binding: I'll write a simple library in C language and I'll show how to create the relative python binding, providing complete source code and an example for python developers.
  • Building and installing python bindings with distutils: I'll explain how to use distutils to build and install the binding (using the well know method "python setup.py install").
  • Defining new types: this post will be about how to write new types in C language and being able to use them from python code.
  • Using codegen to write bindings: I'll explain how to use codegen utils to automate lot of tasks, to generate the most part of binding code and how to customize the generated code using overrides.

I officially joined the PyMaemo team

Posted on Sat 25 July 2009 in Igalia, Linux, Maemo (EN), Programmazione, Python • Tagged with bindings, freemantle, Igalia, maemo, Python

This summer I'm working for 2 months at Igalia, a spanish free software company, and they assigned me the project of writing a Python binding for MAFW (a new multimedia library that will be included in Freemantle).

After few days I discovered that PyMaemo team was already working to it, so I asked to join them and they accepted me!

I really love Python language and since I think other developers love it too, I think we should provide good bindings for every library available in Maemo, so lot of developers can start writing their applications in this language.

I'll work to this project full time until the first week of september, so I hope to be able to learn a lot and to contribute as much as I can to this project.

If anyone else want to join PyMaemo team and help us to develop Python bindings, I think he will be welcome!