使用 pythons Gio-Bindings 在 DBus 上注册一个对象
Registering an Object on DBus using pythons Gio-Bindings
我正在研究现有 C 项目的 Python-克隆。 C 项目连接到自定义 DBus 并在那里提供一个对象以获取回调。
我尝试使用 Python 复制它,代码基本上可以归结为:
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)
在 vtable.method_call
调用中创建 vtable 时代码失败(但 get_property
也失败,当我评论一个调用时)以下 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
我无法在 python 中找到使用 register_object()
的代码,所以我不确定 Gio 的这一部分是否应该可用或者它是否不完整。
这当然不是您想要听到的,但是您在 GDBus Python 绑定中遇到了 4 year old bug,这使得无法在总线上注册对象。很久以前就提出了一个补丁,但每次看起来它真的要登陆时,一些 GNOME 开发人员发现一些 he/she 不喜欢它的东西,提出了一个新补丁......但没有接下来一年的大部分时间都发生了。这个循环已经发生了3次不知道有没有希望很快被打破...
基本上 GNOME 开发人员本身或多或少 suggested that people use dbus-python until this issue is finally fixed, so I guess you should be heading here instead。 :-/
顺便说一句:我认为你的源代码是错误的(除了它不会以任何方式工作的事实)。要创建 VTable,你实际上会这样写,我认为:
vtable = Gio.DBusInterfaceVTable()
vtable.method_call = vtable_method_call_cb
vtable.get_property = None
vtable.set_property = None
但是由于绑定被破坏,您只是在此处使用 abort()
进行异常交易... :-(
如果补丁实际上以当前形式进入 python-gi
,vtable
将被完全转储(是的!)并且 connection.register_object
调用将变为:
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
更新
看来这个问题终于解决了!您现在可以使用 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)
我正在研究现有 C 项目的 Python-克隆。 C 项目连接到自定义 DBus 并在那里提供一个对象以获取回调。
我尝试使用 Python 复制它,代码基本上可以归结为:
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)
在 vtable.method_call
调用中创建 vtable 时代码失败(但 get_property
也失败,当我评论一个调用时)以下 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
我无法在 python 中找到使用 register_object()
的代码,所以我不确定 Gio 的这一部分是否应该可用或者它是否不完整。
这当然不是您想要听到的,但是您在 GDBus Python 绑定中遇到了 4 year old bug,这使得无法在总线上注册对象。很久以前就提出了一个补丁,但每次看起来它真的要登陆时,一些 GNOME 开发人员发现一些 he/she 不喜欢它的东西,提出了一个新补丁......但没有接下来一年的大部分时间都发生了。这个循环已经发生了3次不知道有没有希望很快被打破...
基本上 GNOME 开发人员本身或多或少 suggested that people use dbus-python until this issue is finally fixed, so I guess you should be heading here instead。 :-/
顺便说一句:我认为你的源代码是错误的(除了它不会以任何方式工作的事实)。要创建 VTable,你实际上会这样写,我认为:
vtable = Gio.DBusInterfaceVTable()
vtable.method_call = vtable_method_call_cb
vtable.get_property = None
vtable.set_property = None
但是由于绑定被破坏,您只是在此处使用 abort()
进行异常交易... :-(
如果补丁实际上以当前形式进入 python-gi
,vtable
将被完全转储(是的!)并且 connection.register_object
调用将变为:
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
更新
看来这个问题终于解决了!您现在可以使用 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)