Python bindings for a vala library
I am trying to create python bindings to a vala library using the following IBM tutorial as a reference.
My initial directory has the following two files:
test.vala
using GLib;
namespace Test {
public class Test : Object {
public int sum(int x, int y) {
return x + y;
}
}
}
test.override
%%
headers
#include <Python.h>
#include "pygobject.h"
#include "test.h"
%%
modulename test
%%
import gobject.GObject as PyGObject_Type
%%
ignore-glob
*_get_type
%%
and try to build the python module source test_wrap.c
using the following code
build.sh
#/usr/bin/env bash
valac test.vala -CH test.h
python /usr/share/pygobject/2.0/codegen/h2def.py test.h > test.defs
pygobject-codegen-2.0 -o test.override -p test test.defs > test_wrap.c
However, the last command fails with an error
$ ./build.sh
Traceback (most recent call last):
File "/usr/share/pygobject/2.0/codegen/codegen.py", line 1720, in <module>
sys.exit(main(sys.argv))
File "/usr/share/pygobject/2.0/codegen/codegen.py", line 1672, in main
o = override.Overrides(arg)
File "/usr/share/pygobject/2.0/codegen/override.py", line 52, in __init__
self.handle_file(filename)
File "/usr/share/pygobject/2.0/codegen/override.py", line 84, in handle_file
self.__parse_override(buf, startline, filename)
File "/usr/share/pygobject/2.0/codegen/override.py", line 96, in __parse_override
command = words[0]
IndexError: list index out of range
Is this a bug in pygobject, or is something wrong with my setup? What is the best way to call code written in vala from python?
EDIT: Removing the extra line fixed the current problem, but now as I proceed to build the python module, I am facing another problem. Adding the following C file to the existing two in the directory:
test_module.c
#include <Python.h>
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 building with the following script
build.sh
#/usr/bin/env bash
valac test.vala -CH test.h
python /usr/share/pygobject/2.0/codegen/h2def.py test.h > test.defs
pygobject-codegen-2.0 -o test.override -p test test.defs > test_wrap.c
CFLAGS="`pkg-config --cflags pygobject-2.0` -I/usr/include/python2.6/ -I."
LDFLAGS="`pkg-config --libs pygobject-2.0`"
gcc $CFLAGS -fPIC -c test.c
gcc $CFLAGS -fPIC -c test_wrap.c
gcc $CFLAGS -fPIC -c test_module.c
gcc $LDFLAGS -shared test.o test_wrap.o test_module.o -o test.so
python -c 'import test; exit()'
results in an error:
$ ./build.sh
***INFO*** The coverage of global functions is 100.00% (1/1)
***INFO*** The coverage of methods is 100.00% (1/1)
***INFO*** There are no declared virtual proxies.
***INFO*** There are no declared virtual accessors.
***INFO*** There are no declared interface proxies.
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: ./test.so: undefined symbol: init_pygobject
Where is the init_pygobject
symbol defined? What have I missed linking to?
You can go with GObject Introspection.
This repository contains samples how to auto-bind vala libraries to other languages:
https://github.com/antono/vala-object
Very bad situation! Writing bindings for pygtk is quite an hell, fortunately they are switching to gobject introspection that will make the things easier..
Anyway it seems that there is an extra newline in the test.override file, try removing that and it should work (at least I've tested it)
Looks like this code is also on Charlie's Second Blog 2008
test_module.c
needs to include <pygobject.h>
:
#include <Python.h>
#include <pygobject.h>
With that change it builds and runs in python with:
>>> import test
>>> t = test.Test()
>>> t.sum(1,2)
3
精彩评论