DBus 在Qt和C++中的使用Demo

一、DBus
DBus(D-Bus)是一种跨进程通信机制,是一种消息总线系统。DBus提供了一种在应用程序之间进行通信和交互的方式,可以在不同的进程之间传递消息,并提供了一套API供开发者使用。



二、Qt中使用
功能:先获取当前用户的路径,在根据路径,通过属性获取用户的昵称。

在 .pro 文件中添加 QtDBus 模块:
QT += core gui dbus

QDBusInterface 参数:

  • D-Bus 服务的名称
  • DBus接口的对象路径
  • 接口名称(一个对象可以实现多个接口,每个接口提供不同的功能)
  • 指定使用哪个 D-Bus 总线进行通信,系统总线是全局的,所有用户和服务都可以访问,而会话总线则特定于每个用户会话。
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusReply>

QString getUserPath()
{
	QString userName = qgetenv("USER");
	const char* server = "org.freedesktop.Accounts";
	const char* path = "/org/freedesktop/Accounts";
	const char* interface = "org.freedesktop.Accounts";

	QDBusInterface dbusInterface(server, path, interface, QDBusConnection::systemBus());
	// 参数指定调用的方法,以及方法的参数
	QDBusReply<QDBusObjectPath> reply = dbusInterface.call("FindUserByName", userName);

	return reply.error().type() == QDBusError::NoError ? reply.value().path() : "";
}

void getNickName(const QString &userPath)
{
	const char* server = "org.freedesktop.Accounts";
	const char* path = userPath.toLatin1().data();
	const char* interface = "org.freedesktop.Accounts.User";

	QDBusInterface dbusInterfaceTwo(server, path, interface, QDBusConnection::systemBus());  
	QString nickName = dbusInterfaceTwo.property("RealName").toString();
	qDebug() << "NickName:" << nickName;
}

int main()
{
	getNickName(getUserPath());
	return 0;
}


三、C++中使用
实现上述同样的功能。

  • 安装DBus
    sudo apt-get install libdbus-1-dev
  • 编译(头文件大写i,链接库小写L)
    gcc two.c -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include/ -ldbus-1
  • 执行
    ./a.out
#include <stdio.h>
#include <stdlib.h>
#include <dbus-1.0/dbus/dbus.h>

DBusConnection *getDBusConnect()
{
    DBusError error;
    dbus_error_init(&error);
    DBusConnection *connect = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
 
    if (dbus_error_is_set(&error)) {
        fprintf(stderr, "Error connecting to system bus: %s\n", error.message);
        dbus_error_free(&error);
        return NULL;
    }

    return connect;
}
  
void call_find_user_by_name(DBusConnection *connect, char **userPath) {
    DBusMessage *message = dbus_message_new_method_call(
        "org.freedesktop.Accounts",
        "/org/freedesktop/Accounts",  
        "org.freedesktop.Accounts",  
        "FindUserByName"  
    );
    const char *userName = getenv("USER");
    dbus_message_append_args(message, DBUS_TYPE_STRING, &userName, DBUS_TYPE_INVALID);

    DBusError error;
    dbus_error_init(&error);
    DBusMessage *reply = dbus_connection_send_with_reply_and_block(connect, message, -1, &error);

    // Failed
    if (dbus_error_is_set(&error)) {
        fprintf(stderr, "Error: %s\n", error.message);
        dbus_error_free(&error);
        return;
    }
    // Success
    dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, userPath, DBUS_TYPE_INVALID);
    
    if (message)
        dbus_message_unref(message);  
    if (reply)
        dbus_message_unref(reply);  
}  

void call_real_name(DBusConnection *connect, char *userPath) { 
    DBusMessage *message = dbus_message_new_method_call(  
        "org.freedesktop.Accounts",  
        userPath,
        "org.freedesktop.DBus.Properties",  
        "Get"
    );  

    const char *interface = "org.freedesktop.Accounts.User";
    const char *property = "RealName";
    if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) {  
        fprintf(stderr, "Out of memory\n");
        dbus_message_unref(message);
        return;
    }  
      
    DBusError error;
    dbus_error_init(&error);
    DBusMessage *reply = dbus_connection_send_with_reply_and_block(connect, message, -1, &error);
      
    if (dbus_error_is_set(&error)) {  
        fprintf(stderr, "Error getting property: %s\n", error.message);  
        dbus_error_free(&error);
        return;
    }

    DBusMessageIter args;
    if (dbus_message_iter_init(reply, &args) && dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_VARIANT) {  
        DBusMessageIter variant;  
        dbus_message_iter_recurse(&args, &variant);  
  
        // VARIANT is a string
        if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_STRING) {
            char *nickName = NULL;
            dbus_message_iter_get_basic(&variant, &nickName);
            printf("Nickname: %s\n", nickName);
        } 
    }  

    if (message)
        dbus_message_unref(message);
    if (reply)
        dbus_message_unref(reply);
}
  
int main()
{
    DBusConnection *connect = getDBusConnect();
    char *userPath = NULL;

    call_find_user_by_name(connect, &userPath);  // 二级指针:可以用来返回多个值,作为输出型参数
    call_real_name(connect, userPath);
    dbus_connection_unref(connect);
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值