Python is a powerful object oriented script language, and vala is a C gobject compiler that makes it easy to generate object oriented code in C. It is quite easy to mix python and vala in a same programme, allowing us to write very quickly modular and fast applications.
So here is how it works :
Let say I have a vala module, that defines one class, with one public method. Here is the file (test.vala) :
using GLib;
namespace Test {
public class Test : Object {
public int sum(int x, int y) {
return x + y;
}
}
}
I can generate the C/gobject code for this module, using vala :
valac -C test.vala
this command will create test.c and test.h. These files are conform C and can be compiled with gcc (in fact these are the files people using gobject in C would write. If we have a look at it, we understand the pain that it is to write gobject code in C !).
But to be able to call the functions from python, we need to create wrapper to the python C interface. This can be easily done using some tools (included in the debian pygtk-dev package). For more information, see this page.
Here are the commands that generate our C python interface :
python /usr/share/pygtk/2.0/codegen/h2def.py test.h > test.defs
pygtk-codegen-2.0 -o test.override -p test test.defs > test_wrap.c
Where 'test.override' is a compulsory file that looks like this :
%%
headers
#include
#include "pygobject.h"
#include "test.h"
%%
modulename test
%%
import gobject.GObject as PyGObject_Type
%%
ignore-glob
*_get_type
%%
Alright we now have a file called test_wrap.c, that contains all the wrapper functions from the python C interface to gobject C.
The next step is to actually create the C library callable from python. this library must contains a function 'inittest' (this is the function that will be called when we import the module from python.) The file looks like this (test_module.c) :
#include
void test_register_classes (PyObject *d);
extern PyMethodDef test_functions[];
DL_EXPORT(void)
inittest(void)
{
PyObject *m, *d;
init_pygobject();
m = Py_InitModule("test", test_functions);
d = PyModule_GetDict(m);
test_register_classes(d);
if (PyErr_Occurred ()) {
Py_FatalError ("can't initialise module test");
}
}
And then we are almost done... finally we compile and link everything :
CFLAGS="`pkg-config --cflags gtk+-2.0 pygtk-2.0` -I/usr/include/python2.5/ -I."
LDFLAGS=`pkg-config --libs gtk+-2.0 pygtk-2.0`
gcc -c -o test.o test.c
gcc $CFLAGS -c test_wrap.c -o test_wrap.o
gcc $CFLAGS -c test_module.c -o test_module.o
gcc $LDFLAGS -shared test.o test_wrap.o test_module.o -o test.so
And now we finally have our library : test.so, that can be directly used from python. Here is our python script (test.py):
import test
t = test.Test()
print t.sum(2,3)
Conclusion :
This combination (python + vala) is ideal to write applications for OpenMoko : there is no need to compile the python part, and since the vala code generate C code, it can be easily compiled for different targets.
So no excuses not to write great apps for OpenMoko :)
4 comments:
While that might be cool and useful for some, I prefer Cython (and hopefully soon, RPython).
I don't see the point of learning yet another barely used C-style language.
I never heard of Cython before ! It looks very promising indeed ! I know pyrex, but I had been quite disappointed with it.
One of the advantage of vala is that you can use the gobject libraries. Also when you write a library in vala you can then use it from several languages, not just python.
That being said, I agree that Cython may be a better choice in general cases. I will definitively spend some time learning it.
Nice work! In the - hopefully not so distant - future, this will get even easier. PyBank will be able to generate Python bindings to GObject libraries on the fly, i.e. you won't need to write .override files or run pygtk-codegen, it will just work.
The information required for the bindings will be read from a GObject Introspection Metadata file, which the Vala compiler can automatically generate.
Wow PyBank is very interesting as well.
As far as I understand it will be somehow similar to the ctypes module, but with the ability to access gobject as well as plain C functions.
I like ctypes a lot, in fact this is what I use most of the time when I want to write a small part of my code in C.
Yeah, I will keep an eye on PyBank.
Post a Comment