Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Output:

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?

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

Output:

***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?

like image 822
D R Avatar asked Aug 24 '26 23:08

D R


2 Answers

You can go with GObject Introspection.

This repository contains samples on how to auto-bind Vala libraries to other languages: vala-object

like image 88
antono Avatar answered Aug 26 '26 13:08

antono


It is a very bad situation! Writing bindings for PyGTK is quite a hell, but fortunately they are switching to GObject Introspection. That will make 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).

like image 36
pygabriel Avatar answered Aug 26 '26 13:08

pygabriel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!