QT绑定D-Bus程序实例

 

参考自:

http://laurii.info/articles/2007/03/22/dbus-and-qt-programmin

 

http://blog.chinaunix.net/u2/69889/showart_2316513.html

 

 

根据第二个BLOG,我改动了部分代码,使用dbus interface调用方式,一步一步建立C/S结构代码:

[socol@localhost testdbus]$ ll

client
hotelibs
service

 

1. 建立库函数hotelibs

[socol@localhost testdbus]$ cd hotelibs

[socol@localhost hotelibs]$ ll

hotel.pro

hotel.cpp
hotel.h

[socol@localhost hotelibs]$cat hotel.h

#ifndef HOTEL_H
#define HOTEL_H

#include <QObject>
#include <QReadWriteLock>

#define MAX_ROOMS       10

class Hotel : public QObject
{
    Q_OBJECT
    // 定义Interface名称为"com.test.hotel.registry"
    Q_CLASSINFO("D-Bus Interface", "com.test.hotel.registry")

public:
    Hotel() { m_rooms = MAX_ROOMS; }

public slots:
    // Check in,参数为房间数,返回成功拿到的房间数
    int checkIn(int num_room);
    // Check out,参数为房间数,返回成功退回的房间数
    int checkOut(int num_room);
    // Query,用于查询目前还剩下的房间数
    int query();

private:
    int m_rooms;
    QReadWriteLock m_lock;
};

#endif // HOTEL_H
 

[socol@localhost hotelibs]$cat hotel.cpp

#include <QtCore>
#include <QtDBus>
#include <QReadLocker>
#include <QWriteLocker>

#include "hotel.h"

int Hotel::checkIn(int num_room)
{
        QWriteLocker locker(&m_lock);

        if (m_rooms >= num_room) {
                m_rooms -= num_room;
        } else {
                num_room = m_rooms;
                m_rooms = 0;
        }

        return num_room;
}

int Hotel::checkOut(int num_room)
{
        QWriteLocker locker(&m_lock);

        m_rooms += num_room;

        if (m_rooms > MAX_ROOMS) {
                num_room -= (m_rooms - MAX_ROOMS);
                m_rooms = MAX_ROOMS;
        }

        return num_room;
}

int Hotel::query()
{
        QReadLocker locker(&m_lock);

        return m_rooms;
}
 

[socol@localhost hotelibs]$ qdbuscpp2xml -A hotel.h -o com.test.hotel.xml

[socol@localhost hotelibs]$ qdbusxml2cpp com.test.hotel.xml -i hotel.h -p hotelInterface

[socol@localhost hotelibs]$ll

com.test.hotel.xml
hotel.cpp
hotel.h
hotelibs.pro
hotelInterface.cpp
hotelInterface.h

[socol@localhost hotelibs]$cat com.test.hotel.xml

<!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.test.hotel.registry">
    <signal name="roomChanged">
      <arg name="num_room" type="i" direction="out"/>
    </signal>
    <method name="checkIn">
      <arg type="i" direction="out"/>
      <arg name="num_room" type="i" direction="in"/>
    </method>
    <method name="checkOut">
      <arg type="i" direction="out"/>
      <arg name="num_room" type="i" direction="in"/>
    </method>
    <method name="query">
      <arg type="i" direction="out"/>
    </method>
  </interface>
</node>
 


[socol@localhost hotelibs]$cat hotelibs.pro

QT += dbus
QT -= gui
TARGET = hotelibs
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = lib
SOURCES += hotelInterface.cpp hotel.cpp
HEADERS += hotelInterface.h hotel.h

 [socol@localhost hotelibs]$qmake-qt4 & make

 [socol@localhost hotelibs]$sudo cp libhotelibs.so* /usr/lib

 

2. 建立服务端service

[socol@localhost testdbus]$ cd service

[socol@localhost service]$ ll

hotelservice.pro
main.cpp

[socol@localhost service]$cat hotelservice.pro

QT += dbus
QT -= gui
TARGET = hotelservice
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
LIBS += -L../hotelibs -lhotelibs
INCLUDEPATH += ../hotelibs


[socol@localhost service]$cat main.cpp

#include <QtCore>
#include <QtDBus>
#include <QReadLocker>
#include <QWriteLocker>

#include "hotel.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 用于建立到session bus的连接
    QDBusConnection bus = QDBusConnection::sessionBus();

    // 在session bus上注册名为"com.test.hotel"的service
    if (!bus.registerService("com.test.hotel")) {
            qDebug() << bus.lastError().message();
            exit(1);
    }

    Hotel my_hotel;

#if 0
    // adaport 方式,需要在hotelibs目录中运行:
    // qdbusxml2cpp com.test.hotel.xml -i hotel.h -a hotelAdaport
    new RegistryAdaptor(my_hotel);
#else
    // 注册名为"/hotel/registry"的object。
    // "QDBusConnection::ExportAllSlots "表示把类Hotel的所有Slot都导出为这个Object的method
    // 如果需要使用signal的话可以使用 QDBusConnection::ExportAllSignals
    bus.registerObject("/hotel/registry", &my_hotel,
                       QDBusConnection::ExportAllSlots);
#endif
    return a.exec();
}

 

[socol@localhost service]$qmake-qt4 & make

[socol@localhost service]$sudo cp hotelservice /usr/libexec/

[socol@localhost service]$sudo vim /usr/share/dbus-1/services/com.test.hotel.service

[socol@localhost service]$cat /usr/share/dbus-1/services/com.test.hotel.service
[D-BUS Service]
Name=com.test.hotel
Exec=/usr/libexec/hotelservice

 

3. 建立客户端client

[socol@localhost testdbus]$ cd client

[socol@localhost client]$ ll

main.cpp
hotelclient.pro

[socol@localhost client]$cat main.cpp

#include <QtCore>
#include <QtDBus>

#include <hotel.h>
#include <hotelInterface.h>

int main(int argc, char *argv[])
{
        int num_room;

        if (argc > 2) {
                fprintf(stderr, "Usage: %s [num_room]\n", argv[0]);
                exit(1);
        }

        if (argc == 2) {
                num_room = QString(argv[1]).toInt();
        } else {
                num_room = 1;
        }

        // 初始化自动生成的Proxy类com::test::hotel::registry
        com::test::hotel::registry myHotel("com.test.hotel",
                                           "/hotel/registry",
                                           QDBusConnection::sessionBus());

        // 调用checkIn
        QDBusPendingReply<int> reply = myHotel.checkIn(num_room);
        // qdbusxml2cpp生成的Proxy类是采用异步的方式来传递Message,
        // 所以在此需要调用waitForFinished来等到Message执行完成
        reply.waitForFinished();
        if (reply.isValid()) {
                num_room = reply.value();
                printf("Got %d %s\n", num_room, (num_room > 1) ? "rooms" : "room");
        } else {
                fprintf(stderr, "Check In fail!\n");
        }

        return 0;
}
 

[socol@localhost client]$cat hotelclient.pro

QT += dbus
QT -= gui
TARGET = hotelclient
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
LIBS += -L../hotelibs -lhotelibs
INCLUDEPATH += ../hotelibs
SOURCES += main.cpp 

 

4.测试

[socol@localhost client]$d-feet

// select query() execut, result 10

[socol@localhost client]$./hotelclient

Got 1 room

[socol@localhost client]$d-feet

// select query() execut, result 9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值