DBus(zh)

(一)  深入浅出DBUS

DBUS是一种BUS,那什么又是BUS,初中时候学英语,学到Bus的时候知道它是公共汽车,坐上Bus可以从一个地方到另一个地方,后来学计算机,知道bus也是总线的意思,总线与公共汽车的不同在于:总线上跑的是计算机信号,公共汽车上坐的是人。所以,DBUS是一种用来做IPC(Inter-process communication),即进程间通信的机制。

为什么要使用DBUS,一个原因在于它的底层用socket实现,又去掉了socket的循环等待,迅速更快。另一个原因是linux的两种桌面坏境KDEGnome的通信机制是不同的(具体怎么不同,我也没有深究),DBUS的一个目标是实现一种能在KDEGnome两种环境下都能运行的IPC。最后,现在使用DBUSIPC的项目越来越多。
(二)什么是DBus?
dbus是freedesktop下开源的Linux IPC通信机制,本身Linux 的IPC通信机制包括,管道(fifo),共享内存,信号量,消息队列,Socket等。 像现在流行的moblin平台就使用了DBUS通信,还有我最近看的bluez 4 也是通过DBUS来交互的。
它是个3层架构的进程间通信系统,包括:
1. 函数库libdbus,用于两个应用程序呼叫联系和交互消息。
2. Message bus daemon,总线守护进程可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。
3. 一系列基于特定应用程序框架的Wrapper库。 比如libdbus-glib, libdbus-python.
参看图1-1, Bus Daemon Process就是运行在linux的daemon(dbus-daemon, 用户可以在/etc/init.d/dbus 操作,stop, start等等), dbus-daemon运行时会调用libdus的库。 在Application Process1里面就是应用层的东西了,应用程序调用特定的应用程序框架的Wrapper库与dbus-daemon进行通信。
在dbus主页上(http://www.freedesktop.org/wiki/Software/dbus)提供了很多Wrapper库, for QT4, JAVA, Perl, C++, Pascal, QT3, .NET, Ruby等等。这个Wrapper库呢其实就是对dbus下层调用做了封装,给上层暴露一个友好的接口。dbus的底层其实也是通过socket通信的。
我再给一张bluez的例子让大家更理解dbus; 有四个应用想与bluz的damon通信,bluez注册到dbus中,其它的应用只需要向dbus要bluez的数据,
dbus负责再和bluez沟通了,但是bluez一定要把接口告诉其它应用。
(三)DBus开发资源

1Connect desktop apps using D-BUS:http://www-128.ibm.com/developerworks/linux/library/l-dbus.html?ca=dgr-lnxw95D-BUS.

这是有关DBUS的简介,附有简单的例程,但例程需要稍做修改才能编译通过,修改后的函数signal_filtersend_ping如下:

static DBusHandlerResult signal_filter(DBusConnection *connection, DBusMessage *message, void *user_data){

    GMainLoop *loop = user_data;

    if(dbus_message_is_signal(message, "org.freedesktop.Local", "Disconnected")){

        g_main_loop_quit(loop);

        return DBUS_HANDLER_RESULT_HANDLED;

    }

    else if(dbus_message_is_signal(message, "com.burtonini.dbus.Signal","Ping")){

        DBusError error;

        const char *str;

        dbus_error_init(&error);

        g_print("signal match\n");

        if(dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)){

            g_print("Ping received : %s\n", str);

        }

        else{

            g_print("Ping received, but error getting message : %s\n", error.message);

            dbus_error_free(&error);

        }

        g_print("sub-function start running end \n");

        return DBUS_HANDLER_RESULT_HANDLED;

    }

    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

}

 

static gboolean send_ping(DBusConnection *bus){

    printf("this is sub function\n");

    DBusMessage *message;

    const char *v_STRING = "Ping!!!";

    message = dbus_message_new_signal("/com/burtonini/dbus/ping", "com.burtonini.dbus.Signal", "Ping");

    dbus_message_set_no_reply(message, TRUE); 

    dbus_message_append_args(message, DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_INVALID);

    dbus_connection_send(bus, message, NULL);

    dbus_message_unref(message);

    g_print("Ping!\n");

    return TRUE;

}

 

2http://hi.baidu.com/zengzhaonong/blog/item/670b98d6e63ae42c07088bae.html

这里的例子给出了DBus上几种消息的发送、接收程序框架,例子很容易看明白,一般在此框架上做些修改即可得到自己需要的代码。

 

3http://blog.csdn.net/fmddlmyy/archive/2008/12/23/3585730.aspx

  这个博客的博主正准备详细深入的介绍DBus的方方面面,博主刚开始讨论DBus不久,博客还在持续更新中,估计博主已经在DBus上已经有深厚的功底,请特别关注

 

4http://blog.chinaunix.net/u1/58649/showart_462468.html

  这里是一个比较全的例子,600多行的程序涉及了DBus的方方面面,有极高的参考价值。

 

5http://blog.csdn.net/cuijpus

          这个博客的博主是做手机开发的,在DBus上也有很深的功底,一些例程很值得学习。

 

6freedesktop.org - Software-dbus.url

          DBus Home,这个是最重要也是最有价值的参考资料,DBus的相关源代码和文档都在这里,另外网站还给出了一些使用DBus的开放源代码项目列表,如果你编写DBus某一方面的代码时遇到困惑,网上又找不到可供参考的例子,到这些open source中去serch相关源代码或许是一个很有效的方法。

 

Comments