http://people.freedesktop.org/~david/gio-gdbus-codegen-20110412/ch29.html

Conceptual differences(概念上的区别)

The central concepts of D-Bus are modelled in a very similar way in dbus-glib and GDBus. Both have a objects representing connections, proxies and method invocations. But there are some important differences:

D-Bus最重要的概念在dbus-glib和GDBus中都是相似的.都用对象表示连接,代理 和 方法执行,但也有一些重要的不同点:

  • dbus-glib uses the libdbus reference implementation, GDBus doesn't. Instead, it relies on GIO streams as transport layer, and has its own implementation for the the D-Bus connection setup and authentication. Apart from using streams as transport, avoiding libdbus also lets GDBus avoid some thorny multithreading issues.

dbus-glib使用 libdbus reference implementation,GDBus不使用,而是依赖GIO流作为传输层,并且拥有一套自己实现的D-Bus连接设置和授权的方法.暂且不说GDBus使用流传输,

不使用libdbus可以使GDBus避免一些多线程方面的问题.

  • dbus-glib uses the GObject type system for method arguments and return values, including a homegrown container specialization mechanism. GDBus relies on the GVariant type system which is explicitly designed to match D-Bus types.

dbus-glib的方法参数和返回值使用Gobject类型系统,其中包含了一个特定结构的自有容器.GDBus依赖专为匹配D-Bus类型而设计的GVariant类型系统.

dbus-glib 只能提供D-Bus接口,不为对象提供任何类型,

GDBus同时提供D-Bus接口(通过GDBusInterfaceGDBusProxy 和 GDBusInterfaceStub 类型)和对象接口(通过GDBusObjectGDBusObjectStub 和 GDBusObjectProxy 类型)

GDBus 为org.freedesktop.DBus.Properties (通过 GDBusProxy 类型) 和 org.freedesktop.DBus.ObjectManager D-Bus接口,包含了本地支持,dbus-glib没有.

  • The typical way to export an object in dbus-glib involves generating glue code from XML introspection data using dbus-binding-tool. GDBus provides a similar tool called gdbus-codegen that can also generate Docbook D-Bus interface documentation.

dbus-glib中导出对象的典型方法是使用dbus-binding-tool根据XML内省数据生成代码,GDBus也提供了一个类似的工具叫做gdbus-codegen,这个工具也可以生成Docbook D-Bus接口文件.

  • dbus-glib doesn't provide any convenience API for owning and watching bus names, GDBus provides the g_bus_own_name() and g_bus_watch_name() family of convenience functions.

dbus-glib不提供战友和监视总线名字的方便的API,GDBus提供了g_bus_own_name() 和g_bus_watch_name() 系列的方便函数.

  • GDBus provides API to parse, generate and work with Introspection XML, dbus-glib doesn't.

GDBus提供API来解析、生成 和 工作的内省XML,dbus-glib不提供。

API comparison

                        Table. dbus-glib APIs and their GDBus counterparts

dbus-glib GDBus
DBusGConnection GDBusConnection
DBusGProxy GDBusProxyGDBusInterface - also see GDBusObjectProxy
DBusGObject GDBusInterfaceStubGDBusInterface - also see GDBusObjectStub
DBusGMethodInvocation GDBusMethodInvocation
dbus_g_bus_get() g_bus_get_sync(), also see g_bus_get()
dbus_g_proxy_new_for_name() g_dbus_proxy_new_sync() and g_dbus_proxy_new_for_bus_sync(), also see g_dbus_proxy_new()
dbus_g_proxy_add_signal() not needed, use the generic "g-signal"
dbus_g_proxy_connect_signal() use g_signal_connect() with "g-signal"
dbus_g_connection_register_g_object() g_dbus_connection_register_object() - also see g_dbus_object_manager_server_export()
dbus_g_connection_unregister_g_object() g_dbus_connection_unregister_object() - also see g_dbus_object_manager_server_unexport()
dbus_g_object_type_install_info() introspection data is installed while registering an object, see g_dbus_connection_register_object()
dbus_g_proxy_begin_call() g_dbus_proxy_call()
dbus_g_proxy_end_call() g_dbus_proxy_call_finish()
dbus_g_proxy_call() g_dbus_proxy_call_sync()
dbus_g_error_domain_register() g_dbus_error_register_error_domain()
dbus_g_error_has_name() no direct equivalent, see g_dbus_error_get_remote_error()
dbus_g_method_return() g_dbus_method_invocation_return_value()
dbus_g_method_return_error() g_dbus_method_invocation_return_error() and variants
dbus_g_method_get_sender() g_dbus_method_invocation_get_sender()

Owning bus names

Using dbus-glib, you typically call RequestName manually to own a name, like in the following excerpt:

使用dbus-glib来占有一个总线名字的典型做法是手动调用RequestName ,像下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
error = NULL;
res = dbus_g_proxy_call (system_bus_proxy,
"RequestName",
&error,
G_TYPE_STRING, NAME_TO_CLAIM,
G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT,
G_TYPE_INVALID,
G_TYPE_UINT, &result,
G_TYPE_INVALID);
if (!res)
{
if (error != NULL)
{
g_warning ("Failed to acquire %s: %s",
NAME_TO_CLAIM, error->message);
g_error_free (error);
}
else
{
g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
}
goto out;
} if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
{
if (error != NULL)
{
g_warning ("Failed to acquire %s: %s",
NAME_TO_CLAIM, error->message);
g_error_free (error);
}
else
{
g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
}
exit (1);
} dbus_g_proxy_add_signal (system_bus_proxy, "NameLost",
G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost",
G_CALLBACK (on_name_lost), NULL, NULL); /* further setup ... */

While you can do things this way with GDBus too, using g_dbus_proxy_call_sync(), it is much nicer to use the high-level API for this:

当然你可以使用GDBus的方式,调用函数g_dbus_proxy_call_sync()来完成同样的功能,但是使用高级的API(g_bus_own_name)是更好地方式.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void
on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
/* further setup ... */
} /* ... */ owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
NAME_TO_CLAIM,
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
on_bus_acquired,
on_name_acquired,
on_name_lost,
NULL,
NULL); g_main_loop_run (loop); g_bus_unown_name (owner_id);

Note that g_bus_own_name() works asynchronously and requires you to enter your mainloop to await the on_name_aquired() callback. Also note that in order to avoid race conditions (e.g. when your service is activated by a method call), you have to export your manager object before acquiring the name. The on_bus_acquired() callback is the right place to do such preparations.

需要注意的是g_bus_own_name 工作方式是异步的,并且需要你进入mainloop来等待on_name_aquired()这个callback被调用.还需要注意的是为了防止条件竞争(例如你的服务是同方法调用来启动的),你必须在就on_name_aquired()回调之前导出管理对象,on_bus_acquired()这个callback中是导出管理对象的正确位置.

Creating proxies for well-known names

dbus-glib lets you create proxy objects for well-known names, like the following example:

1
2
3
4
proxy = dbus_g_proxy_new_for_name (system_bus_connection,
"org.freedesktop.Accounts",
"/org/freedesktop/Accounts",
"org.freedesktop.Accounts");

For a DBusGProxy constructed like this, method calls will be sent to the current owner of the name, and that owner can change over time.

The same can be achieved with GDBusProxy:

1
2
3
4
5
6
7
8
9
error = NULL;
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL, /* GDBusInterfaceInfo */
"org.freedesktop.Accounts",
"/org/freedesktop/Accounts",
"org.freedesktop.Accounts",
NULL, /* GCancellable */
&error);

For an added layer of safety, you can specify what D-Bus interface the proxy is expected to conform to by using the GDBusInterfaceInfo type. Additionally, GDBusProxy loads, caches and tracks changes to the D-Bus properties on the remote object. It also sets up match rules so D-Bus signals from the remote object are delivered locally.

The GDBusProxy type normally isn't used directly - instead proxies subclassing GDBusProxy generated by gdbus-codegen is used, see the section called “Using gdbus-codegen”

 
 

dbus-glib 和 GDBus 的区别的更多相关文章

  1. DBus介绍

    1. 介绍 DBus是一种桌面环境的进程间通讯(IPC)机制,有低时延.低消耗等优点 基于socket,提供了一对一的对等通讯:使用dbus-daemon作为后台进程时,可实现多对多通讯 由如下三个层 ...

  2. Dbus组成和原理

    DBUS是实质上一个适用于桌面应用的进程间的通讯机制,即所谓的IPC机制.适合在同一台机器,不适合于INTERNET的IPC机制.DBUS不是一个为所有可能的应用的通用的IPC机制,不支持其他IPC机 ...

  3. dbus客户端使用指南

    DBus是Linux使用的进程间通信机制,允许各个进程互相访问,而不需要为每个其他组件实现自定义代码.即使对于系统管理员来说,这也是一个相当深奥的主题,但它确实有助于解释linux的另一部分是如何工作 ...

  4. Linux 常用命令:系统状态篇

    前言 Linux常用命令中,有些命令可以用于查看系统的状态,通过了解系统当前的状态,能够帮助我们更好地维护系统或定位问题.本文就简单介绍一下这些命令. 1. 查看系统运行时间--uptime 有时候我 ...

  5. DBus send byte array over gdbus ----Send dbus data

    遇到一个问题,如何通过dbus传送uint8数组元素 有3种方法, 1.直接传 ay 2.传  a(y) 3.xml定义为 ay,但是通过annotation 强行将 guchar 转为GVarian ...

  6. [转帖]glib gslibc libc 的关系与区别

    https://blog.csdn.net/Com_ma/article/details/78692092 [glibc 和 libc] glibc 和 libc 都是 Linux 下的 C 函数库. ...

  7. glibc, eglibc和 glib的区别

    http://blog.csdn.net/wind19/article/details/6082874

  8. dbus 和 policykit 实例篇(python) ()转

    使用policykit 的程序一般都有一个dbus daemon程序来完成相关操作,这个dbus daemon 会在系统注册一个system bus 服务名,用于响应要求root privileged ...

  9. DBus学习笔记

    摘要:DBus作为一个轻量级的IPC被越来越多的平台接受,在MeeGo中DBus也是主要的进程间通信方式,这个笔记将从基本概念开始记录笔者学习DBus的过程 [1] DBus学习笔记一:DBus学习的 ...

随机推荐

  1. (十六)qt-udp,组播

    基本流程 简单聊天程序 #include "server.h" #include <QApplication> #include "client.h" ...

  2. APP 后台学习笔记

    1.APP后台功能: 远程存储数据.消息中转 2.架构是业务驱动,可能随着开发进程而变化,没有最完美架构 3.架构不要满足追求技术新奇酷炫,而是结合具体业务使用合适的技术,否则会给运维带来很多不必要的 ...

  3. django 4.get接口开发

    根据上一篇文章,有post,那么就有get请求,其余部分不变,就是把post换成get就可以. #views.py from django.http.response import HttpRespo ...

  4. python_类与对象学习笔记

    class Phone: #手机属性===>类属性 # color='black' # price=4500 # brand='oppo' # size='5.5' #参数化-魔法方法--初始化 ...

  5. django-crontab实现定时任务

    django-crontab实现服务端的定时任务 安装 pip install django-crontab 在Django项目中使用 settings.py INSTALLED_APPS = ( ' ...

  6. sshpass-Linux命令之非交互SSH密码验证

    sshpass-Linux命令之非交互SSH密码验证 参考网址:https://www.cnblogs.com/chenlaichao/p/7727554.html ssh登陆不能在命令行中指定密码. ...

  7. jmeter 多个sql写在一个jdbc请求中注意事项

    在url里面加上?allowMultiQueries=true 类型选callableStatement

  8. Linux中errno的含义

    /****************************获取错误代码描述**************/ #include <string.h>#include <errno.h&g ...

  9. node服务端口被占用Error listen EADDRINUSE :::3000

    Error: listen EADDRINUSE: address already in use :::3000,出现这个报错说明3000端口被占用 解决方法:找到占用该端口的程序,kill杀掉它就可 ...

  10. Go语言入门: Chapter1

    书籍官网: http://www.gopl.io 环境配置: https://studygolang.com/articles/8284  安装go和vscode中go的相关插件 主要命令学习: go ...