python - 使用 pythons Gio-Bindings 在 DBus 上注册一个对象

标签 python dbus gio

我正在研究现有 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 也失败,当我评论一个调用时)以下日志/回溯:

** (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 的这一部分是否应该可用或者它是否不完整。

最佳答案

这当然不是你想听到的,但你已经打了4 year old bug在 GDBus Python 绑定(bind)中,这使得无法在总线上注册对象。很久以前就提出了一个补丁,但是每次看起来它真的要登陆时,一些 GNOME 开发人员发现了一些他/她不喜欢它的东西,提出了一个新的补丁......但没有任何反应明年的大部分时间。这个循环已经发生了3次,不知道有没有希望很快被打破...

基本上 GNOME 开发人员自己或多或少 suggested that people use dbus-python until this issue is finally fixed , 所以我想你应该去 here instead . :-/

顺便说一句:我认为你的源代码是错误的(除了它不会以任何方式工作的事实)。要创建 VTable,我认为您实际上应该这样写:

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

但由于绑定(bind)被破坏,你只是在此处用 abort() 进行异常交易...... :-(

如果补丁实际上以当前形式进入 python-givtable 将被完全转储(是的!)和 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)

关于python - 使用 pythons Gio-Bindings 在 DBus 上注册一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28030314/

相关文章:

python - 如何使用 Flask 从选择标签访问值?

bluetooth-lowenergy - 蓝Z 5.30 : D-Bus GATT API - Simply Discover and Connect to a BLE device in C

linker-errors - D-Bus 链接问题

javascript - JS, "objects",这个那个。来自 python 这真的让我感到困惑。 (双关语)

python - 使用 selenium python 发送 key 无效

python - 我可以提供生成的图像而不将它们存储在服务器端吗?

python - BlueZ DBUS API - GATT 接口(interface)对 BLE 设备不可用

c - 如果 GInterface 方法签名与 VirtualTable (struct) 方法不匹配怎么办?

c - Glib/Gio 异步或线程 UDP 服务器