使用QtDBus作为Qt的进程通信

自从Qt-4.2版本引入D-Bus作为进程通信的一个方法之后,它就越来越有取代qcop的趋势。它不仅在应用层之间可以互相通信,还可以和内核做通信。比如某些硬件事件的发生,就可以通过D-Bus来交互。Linux系统中的蓝牙bluez正是使用了这种D-Bus.

那我们就来看看在我们的Qt应用中怎么使用QtDBus功能。

作为服务器端,我们需要做的工作有:
1. 申请一个总线连接
2. 在总线连接上挂载服务,这样其他进程才能请求该服务
3. 在挂载的服务上注册一个执行服务的对象

作为服务请求端,我们需要做的工作有:
a. 申请一个总线连接
b. 创建一个接口,连接到要请求的服务上
c. 正式发送请求

我们分别来看看对应的步骤,我们应该做什么操作
1.和a.在代码上是完全一样的。

if (!QDBusConnection::sessionBus().isConnected()) {
    fprintf(stderr, "Cannot connect to the D-Bus session bus./n"
    "To start it, run:/n"
    "/teval `dbus-launch --auto-syntax`/n");
    return 1;
}

sessionBus()是一个静态函数,返回当前的一个QDBusConnection连接,如果原来没有则创建一个.

2. 使用registerService函数去注册,SERVICE_NAME可以随便写,我这里写的是com.cuteqt.blogexample

if (!QDBusConnection::sessionBus().registerService(SERVICE_NAME)) {
    fprintf(stderr, "%s/n",
    qPrintable(QDBusConnection::sessionBus().lastError().message()));
    exit(1);
}

执行完这一步后,你可以使用Qt带的工具,qdbusviewer就能看到com.cuteqt.blogexample已经注册上了

3. qtqt是我的QtQt类的几个对象,将其注册到总线上,这个提供服务的就是QtQt的类函数

QtQt qtqt;
QDBusConnection::sessionBus().registerObject("/", &qtqt, QDBusConnection::ExportAllSlots);

b. 这一步注意SERVICE_NAME的名字和服务器端的代码一样即可,可以判断iface.isValid()

QDBusInterface iface(SERVICE_NAME, "/", "", QDBusConnection::sessionBus());

c. 真正发出具体的总线服务内容请求

QDBusReply reply = iface.call("blogurl","bug");
if (reply.isValid()) {
printf("Reply was: %s/n", qPrintable(reply.value()));
return 0;
}
else{
fprintf(stderr, "Call failed: %s/n", qPrintable(reply.error().message()));
return 1;
}

我们注意这个blogurl()请求名字就是我们在服务器端注册对象qtqt的类函数,bug是我们传送过去的参数

完整源码下载请点击
服务器端和请求端在一个应用里。运行的时候将一份可执行档拷贝名字为client的就可以。先运行服务端,再运行client。
代码就50几行,很好理解,能演示功能。但不鲁棒:)

你可能感兴趣的:(技术)