以下是一个简单的 D-Bus (QDBus) 应用示例,演示客户端调用服务端方法并获取返回值:
场景:远程获取问候语
目标:客户端通过 D-Bus 调用服务端的 GetGreeting
方法,返回自定义问候语。
步骤 1:定义 D-Bus 接口
创建接口文件 com.example.Greeter.xml
:
<node>
<interface name="com.example.Greeter">
<method name="GetGreeting">
<arg type="s" name="name" direction="in"/>
<arg type="s" name="greeting" direction="out"/>
</method>
</interface>
</node>
步骤 2:实现服务端
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDebug>
class GreeterService : public QObject {
Q_OBJECT
public:
explicit GreeterService(QObject *parent = nullptr) : QObject(parent) {
// 注册 D-Bus 对象和服务
QDBusConnection::sessionBus().registerObject("/Greeter", this);
QDBusConnection::sessionBus().registerService("com.example.Greeter");
}
public slots:
QString GetGreeting(const QString &name) {
return QString("Hello, %1! Welcome to D-Bus!").arg(name);
}
};
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
GreeterService service;
return a.exec();
}
步骤 3:实现客户端
#include <QCoreApplication>
#include <QDBusInterface>
#include <QDebug>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// 连接 D-Bus 会话总线
QDBusInterface iface(
"com.example.Greeter", // 服务名
"/Greeter", // 对象路径
"com.example.Greeter", // 接口名
QDBusConnection::sessionBus()
);
// 调用远程方法
QDBusReply<QString> reply = iface.call("GetGreeting", "Alice");
if (reply.isValid()) {
qDebug() << "Received greeting:" << reply.value();
} else {
qWarning() << "Error:" << reply.error().message();
}
return 0;
}
步骤 4:编译与运行
-
编译服务端:
qmake -project "QT += dbus" qmake make ./your_service_executable
-
编译客户端(需确保服务端已运行):
qmake -project "QT += dbus" qmake make ./your_client_executable
输出:
Received greeting: "Hello, Alice! Welcome to D-Bus!"
关键点说明:
- 接口定义:通过 XML 文件明确方法签名(输入/输出参数类型)。
- 服务注册:服务端通过
registerService
和registerObject
暴露接口。 - 方法调用:客户端使用
QDBusInterface::call
同步调用远程方法。 - 会话总线:示例使用
sessionBus
(用户级通信),系统级服务需改用systemBus
。
扩展建议:
- 添加异步调用(使用
QDBusPendingCall
)。 - 监听服务端信号(如状态更新)。
- 结合 Qt 信号槽机制实现事件驱动架构。