使用DBus监听总线上的消息(仅源码实例)

使用DBus监听总线上的消息(仅源码实例)

使用DBus兼通类型为消息的总线信息。

/*

此程序仅仅是为了在C++语言环境体验一下dbus的基本使用。要执行此程序你的电脑上需要安装
好dbus,且dbus版本应该大于或等于1.0。需要注意一点,头文件dbus.h的路径可能是(至少
我电脑上是):/usr/include/dbus-1.0/dbus/dbus.h,而我电脑上的默认包含路径是
/usr/include,这意味着包含dbus/dbus.h是无法真的包含到头文件dbus.h的。另外一点,
有个头文件dbus-arch-deps.h是在/usr/lib/x86_64-linux-gnu/dbus-1.0/include/dbus
下的,这个目录我是怎么知道的?因为我是找不到了,用了pkg-config --cflags dbus-1去看的。
因此编译和执行需要注意使用CMAKE_CXX_FLAGS:

cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/tmp/test \
-DCMAKE_CXX_FLAGS="-I/opt/dbus/include/dbus-1.0 -I/opt/dbus/lib/dbus-1.0/include -L/opt/dbus/lib" \
-DCMAKE_INSTALL_RPATH=/opt/dbus/lib \
-S . -B build && cmake --build build && build/8_dbus

*/
#include <dbus/dbus.h>
#include <iostream>

/* 通过信号进行通信是dbus中的一种常用方法。这里先试一下这种。 */
class ExampleClassA {
    public:
        void mainMethod();
};

void ExampleClassA::mainMethod() {
    using namespace std;
    cout << "进程开始执行,请等待" << endl;
    auto err = new DBusError();
    dbus_error_init(err);
    auto conn = dbus_bus_get(DBUS_BUS_SESSION, err);
    if (nullptr != conn) {
        dbus_connection_unref(conn);
    } else {
        cout << "发生错误:" << endl;
        cout << err->name << endl;
        cout << err->message << endl;
        dbus_error_free(err);
        delete err;
    }

    cout << "获取会话总线成功,连接对象地址:" << (void*)conn << endl;
    /* 配置过滤器,只接受给定接口的信号 */
    dbus_bus_add_match(conn, "type='signal',interface='org.gnome.Shell.Introspect'", err);
    DBusMessage* message;
    while (dbus_connection_read_write_dispatch(conn, 10000)) { // 设置超时时间,毫秒,等待消息的到来
        cout << "等待结束,判断是否有消息。" << endl;
        message = dbus_connection_borrow_message(conn);
        if (nullptr != message) {
            cout << "有消息,消息相关的信息是:" << endl;
            cout << "消息发送方为:" << dbus_message_get_sender(message) << endl;
            cout << "消息成员:" << dbus_message_get_member(message) << endl;
            cout << "消息接口:" << dbus_message_get_interface(message) << endl;
            cout << "消息路径:" << dbus_message_get_path(message) << endl;
            dbus_connection_return_message(conn, message);
        }
    }
}

int main() {
    ExampleClassA().mainMethod();
    return 0;
}

CMakeLists.txt的内容:

cmake_minimum_required(VERSION 3.12)
project(8_dbus)

option(BUILD_SHARED_LIBS "构建共享对象库" ON)

add_executable(8_dbus main.cpp)
target_link_libraries(8_dbus PUBLIC dbus-1)

install(TARGETS 8_dbus DESTINATION bin)

程序执行效果截图:

DBus接受消息的演示程序如果想要查看系统中有怎么样的DBus传输,可以执行:

/opt/dbus/bin/dbus-monitor

/opt/dbus是我编译安装的dbus路径,系统有点问题,做的时候没有办法用apt安装dbus的dev包,临时找dbud源码编译出来的dbus。

DBus(D-Bus)系统中,为了监听连接断开的信号,你需要首先创建一个DBus服务提供者,并在其上声明一个信号信号通常用于在组件之间传递状态更改信息。以下是基本步骤: 1. **导入必要的库**:在Python中,你可以使用`dbus-python`库来操作DBus。先安装它,然后导入: ```python import dbus from dbus.mainloop.glib import DBusGMainLoop ``` 2. **初始化DBus**:设置主循环,因为DBus需要它: ```python DBusGMainLoop(set_as_default=True) bus = dbus.SessionBus() ``` 3. **定义服务和信号**:创建一个接口和信号,比如`com.example.MyService`,并定义一个表示连接断开的信号如`Disconnected`: ```python interface_name = 'com.example.MyService' signal_name = 'Disconnected' @dbus.service.signal(interface_name, signature='()') def disconnected(): pass ``` 4. **注册服务**:通过`register_object()`方法将包含信号的对象注册到总线上: ```python service_path = '/' + interface_name service = dbus.service.Object(__name__, service_path) bus.add_signal_receiver(signal=disconnected, signal_name=signal_name, object_path=service_path, interface_name=interface_name) ``` 5. **监听连接**:如果你想要在连接断开时执行某些操作,可以在`mainloop`上挂起事件处理函数: ```python def on_connection_closed(*args): print("Connection closed") # 在这里添加你的清理或处理断开逻辑 loop = GLib.MainLoop() loop.run() # 或者在某个特定条件下结束监听 if some_condition: bus.remove_signal_receiver(on_connection_closed, signal_name, interface_name, service_path) loop.quit() ``` 当你完成以上步骤后,其他应用程序可以通过调用你的服务提供的`Disconnected`信号来通知你连接已经断开。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值