Peter Körner Peter Körner - 4 months ago 8
Python Question

Registering an Object on DBus using pythons Gio-Bindings

I'm working on a Python-Clone of an existing C-Project. The C-Project Connects to a custom DBus and offers a Object there for getting Callbacks.

I tried to replicate this using Python with code that basically boils down to:

def vtable_method_call_cb(connection, sender, object_path, interface_name, method_name, parameters, invocation, user_data):
print('vtable_method_call_cb: %s' % method_name)

connection = Gio.DBusConnection.new_for_address_sync(
"unix:abstract=gstswitch",
Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
None,
None)

node_info = Gio.DBusNodeInfo.new_for_xml(introspection_xml)

vtable = Gio.DBusInterfaceVTable()
vtable.method_call(vtable_method_call_cb)
vtable.get_property(None)
vtable.set_property(None)

connection.register_object(
"/info/duzy/gst/switch/SwitchUI",
node_info.interfaces[0],
vtable,
None,
None)


The code fails when creating the vtable at the
vtable.method_call
call (but
get_property
fails, too, when I comment one call out) the following log/traceback:

** (process:18062): WARNING **: Field method_call: Interface type 2 should have is_pointer set
Traceback (most recent call last):
File "moo.py", line 69, in <module>
vtable.method_call(vtable_method_call_cb)
RuntimeError: unable to get the value


I was not able to find code using
register_object()
in python, so I'm unsure if this part of Gio should be usable or if it's just not complete.

Answer

This certainly not what you'll want to hear, but you have hit a 4 year old bug in the GDBus Python bindings that makes it impossible to register objects on the bus. A patch had been proposed quite some time ago, but every time it looked like it was actually going to land, some GNOME developer found something he/she did not like something about it, a new patch was proposed... and nothing happend for most of the next year. This cycle has already happend 3 times and I do not know if there is much hope that it will be broken anytime soon...

Basically the GNOME developers themselves more or less suggested that people use dbus-python until this issue is finally fixed, so I guess you should be heading here instead. :-/

BTW: I think you source code is wrong (aside from the fact that it won't work either way). To create the VTable you would actually be written something like this, I think:

vtable = Gio.DBusInterfaceVTable()
vtable.method_call  = vtable_method_call_cb
vtable.get_property = None
vtable.set_property = None

But since the bindings are broken you are just trading an exception with an abort() here... :-(

If the patch actually makes it into python-gi in the current form the vtable would be dumped entirely (YEAH!) and connection.register_object call would become:

connection.register_object_with_closures(
    "/info/duzy/gst/switch/SwitchUI",
    node_info.interfaces[0],
    vtable_method_call_cb, # vtable.method_call
    None,                  # vtable.get_property
    None)                  # vtable.set_property

Update

It appears this has now finally been fixed! You can now export object using g_dbus_connection_register_object_with_closures:

def vtable_method_call_cb(connection, sender, object_path, interface_name, method_name, parameters, invocation, user_data):
    print('vtable_method_call_cb: %s' % method_name)

connection = Gio.DBusConnection.new_for_address_sync(
    "unix:abstract=gstswitch",
    Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
    None,
    None)

node_info = Gio.DBusNodeInfo.new_for_xml(introspection_xml)

connection.register_object(
    "/info/duzy/gst/switch/SwitchUI",
    node_info.interfaces[0],
    vtable_method_call_cb,
    None,
    None)