使用 gdbus-codegen 骨架时如何验证 D-Bus 属性

Posted

技术标签:

【中文标题】使用 gdbus-codegen 骨架时如何验证 D-Bus 属性【英文标题】:How to validate a D-Bus property when using gdbus-codegen skeleton 【发布时间】:2016-09-29 05:44:39 【问题描述】:

我正在使用 gdbusgdbus-codegen 在 D-Bus 上创建服务。

自省是这样的:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
                      "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="com.example.foo">

    <property name="Bar" type="s" access="readwrite" />

  </interface>
</node>

我正在像这样执行gdbus-codegen

gdbus-codegen --interface-prefix com.example --generate-c-code=foo foo.xml

我的 main.cpp 看起来像这样:

#include <iostream>

#include "foo.h"

void OnBarChanged(GObject * gobject, GParamSpec * pspec, gpointer user_data)

  std::cout << "Bar: " << foo_get_bar((Foo *)gobject) << std::endl;


void OnBusNameAquired(GDBusConnection * connection,
                      const gchar *     name,
                      gpointer          user_data)

  Foo * foo = foo_skeleton_new();

  g_signal_connect(foo, "notify::bar", G_CALLBACK(&OnBarChanged), NULL);

  g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(foo),
                                   connection,
                                   "/com/example/foo",
                                   NULL);


int main()

  std::cout << "Testing DBus properties" << std::endl;

  GMainLoop * loop;
  loop = g_main_loop_new(NULL, FALSE);
  g_bus_own_name(G_BUS_TYPE_SESSION,
                 "com.example.foo",
                 G_BUS_NAME_OWNER_FLAGS_NONE,
                 NULL,
                 OnBusNameAquired,
                 NULL,
                 NULL,
                 NULL);
  g_main_loop_run(loop);
  return 0;

这按预期工作,我可以使用以下方法设置和获取属性:

gdbus call --session --dest com.example.foo --object-path /com/example/foo --method org.freedesktop.DBus.Properties.Set "com.example.foo" "Bar" "<'baz'>"

gdbus call --session --dest com.example.foo --object-path /com/example/foo --method org.freedesktop.DBus.Properties.Get "com.example.foo" "Bar"
(<'baz'>,)

问题:

我想同步验证属性的设置,如果失败能够返回错误。如何使用gdbus-codegen 生成的代码来实现这一点?

PS:

代码泄漏,通常无法用于生产。我现在很好:-)

编辑

经过继续研究,似乎 D-Bus 属性正在使用底层的 GObject 属性功能。当所有这些都由gdbus-codegen-code 设置时,是否可以安装自定义验证器?

【问题讨论】:

【参考方案1】:

从您的foo 骨架连接到GDBusInterfaceSkeleton::g-authorize-method 信号。您的回调将为您导出的对象处理的每个 D-Bus 方法调用调用 - 您可以匹配 org.freedesktop.DBus.Properties.Set 调用然后进行验证。

flatpak 中有一个这样的例子(用于任意方法调用,不是 D-Bus 属性设置;但原理相同):https://github.com/flatpak/flatpak/blob/c915f73b41688a7dc2ec7f0ab2fbcf1a7c738841/system-helper/flatpak-system-helper.c#L1192

【讨论】:

以上是关于使用 gdbus-codegen 骨架时如何验证 D-Bus 属性的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 非常简单的表单验证(骨架)

如何在 swift 中使用多个部分的骨架加载?

如何使用 python 库在骨架图像中找到循环?

使用骨架 css 框架时,边距出现在两个尺寸上

如何提高使用 medial_axis 制作的骨架的质量

如何使用骨架网格垂直对齐图像旁边的文本