DBUS的理解

DBUS的理解dbus 是一个轻量级的 IPC 用于进程间通信或进程与内核间的通信 dbus 通信结构下图 Bus daemon 总线守护进程 dbus 是点对点进行通信的 所以基本上 dbus 进程连接的都是 bus daemon bus daemon 负责将收到的 dbus 消息进行路由 转发

大家好,我是讯享网,很高兴认识大家。

dbus是一个轻量级的IPC,用于进程间通信或进程与内核间的通信,dbus通信结构下图:


讯享网

Bus daemon:总线守护进程,dbus是点对点进行通信的,所以基本上dbus进程连接的都是bus daemon,bus daemon负责将收到的dbus消息进行路由、转发。dbus进程将消息发送给bus daemon,bus daemon会结合消息的目标地址、对象路径、消息的类型、以及dbus进程希望收到的消息进行综合,然后转发。

下面是一个dbus进程连接的结构:

System bus:一个持久的系统总线,在引导时就会启动。由操作系统和后台使用,安全性好。普通进程也可以连接到这个总线上接收消息,但是发送消息却是受限的。

Session bus:用户登录后启动,属于那个用户的私有总线。是用户的应用程序间用来通信的一个总线。

Dbus 的连接:一个dbus进程向后台dbus进行连接,会得要一个连接名(bus name),bus name有两种情况:公共名、唯一名。每个dbus连接一定会有一个唯一名,且唯一名在整个后台dbus的生命周期内唯一。如下图,“:1.0”是唯一名,“org.xfce.xfdesktop”是公共名,如下图:

 

Object path:dbus连接下面可以有多个object path,如bluez连接下面有bluez、bluez/hciconfig等,个人认为之所以有object path,是为了区分不同的服务,如bluez可以理解为蓝牙的协议层,而hciconfig是控制层;

Interface:object path 下面也有很多接口,以bluez为例,下面存在Adapter1、AgentManager1等;

Method:每个interface下也有很多接口,以Adapter1为例,下面有startDiscovery、stopDiscovery等方法;而Method又分为四类:

(1). Method call消息:进程发送消息(目标连接名、对象路径、接口、方法、方法参数)到bus daemon上,bus daemon收到消息后,根据消息的目标名、对象路径,发送到目标进程上,目标进程收到后,使用发送过来的参数,执行这个方法;

(2). Method return 消息:在上述结果执行完成后,一些需要返回结果的接口,会通过这个接口将结果返回回去。

(3). signal消息:希望收到此信号的dbus进程需要在后台dbus上注册,表示自己希望收到这个信号消息,当bus daemon收到此消息时,会将消息转发给注册此信号的进程。

(4). Error消息:

通信示意图

 

下面代码是一个Method call消息的内容:

int a = 2, b = 3; msg = dbus_message_new_method_call("test.wei.dest", "/test/method/Object", "test.method.type", "Method"); DBusMessageIter iter; dbus_message_iter_init_append(msg, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &a); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &b);

讯享网

上面代码中消息的内容包括了目标连接、对象路径、接口、方法、参数。这样bus daemon就可以根据消息的内容,进行转发到test.wei.dest的连接上,并在目标连接的进程内使用参数a、b执行Method这个方法。相当于是test.wei.dest对外提供了一个Method的方法,供外部使用。

下面是一个自发自收的demo:

讯享网#include<stdio.h> #include<stdlib.h> #include<dbus/dbus.h> //消息循环处理,对外提供了两个方法,Add、Quit; DBusHandlerResult dbus_message_handler(DBusConnection* conn, DBusMessage* msg, void* user_data) { if (dbus_message_is_method_call(msg, "com.example.Calculator", "Add")) { // 处理 Add 方法 DBusMessageIter iter; int a, b, sum; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &a); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &b); sum = a + b; DBusMessage* reply = dbus_message_new_method_return(msg); DBusMessageIter reply_iter; dbus_message_iter_init_append(reply, &reply_iter); dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &sum); dbus_connection_send(conn, reply,NULL); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call(msg, "com.example.Calculator", "Quit")) { // 处理 Quit 方法 dbus_connection_close(conn); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } //收到的应答消息处理 void dbus_reply_handler(DBusPendingCall* pending, void* user_data) { int* sum = (int*)user_data; DBusMessage* reply =dbus_pending_call_steal_reply(pending); DBusMessageIter iter; if (reply) { if (dbus_message_iter_init(reply, &iter)) { dbus_message_iter_get_basic(&iter, sum); printf("The sum is: %d\n", *sum); } dbus_message_unref(reply); } dbus_pending_call_unref(pending); } int main() { DBusError error; DBusConnection* conn; DBusMessage* msg; DBusPendingCall* pending; int sum = 0; DBusObjectPathVTable dbus_interface = { .message_function = &dbus_message_handler }; dbus_error_init(&error); // 建立到会话总线的连接 conn = dbus_bus_get(DBUS_BUS_SESSION, &error); if (dbus_error_is_set(&error)) { fprintf(stderr, "Error connecting to system bus: %s\n", error.message); dbus_error_free(&error); return EXIT_FAILURE; } // 注册对象路径和消息处理函数 dbus_bus_request_name(conn, "com.example.Calculator", 0, &error); //向dbus申请公共名 if (dbus_error_is_set(&error)) { fprintf(stderr, "Error requesting name: %s\n", error.message); dbus_error_free(&error); return EXIT_FAILURE; } dbus_connection_register_object(conn, "/com/example/Calculator", &dbus_interface, NULL); // 创建DBus消息,并将参数添加到消息中 int a = 2, b = 3; msg = dbus_message_new_method_call("com.example.Calculator", "/com/example/Calculator", "com.example.Calculator", "Add"); DBusMessageIter iter; dbus_message_iter_init_append(msg, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &a); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &b); // 发送DBus消息并等待应答 dbus_connection_send_with_reply(conn, msg, &pending, -1); dbus_message_unref(msg); dbus_pending_call_set_notify(pending, dbus_reply_handler, &sum, NULL); //将应答消息放到dbus_reply_handler去处理 while (dbus_connection_read_write_dispatch(conn, -1)) { } while(1); dbus_connection_unref(conn); //销毁连接 return EXIT_SUCCESS; } 

参考:https://blog.csdn.net/yishuige/article/details/

小讯
上一篇 2025-03-28 13:02
下一篇 2025-01-16 15:09

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/59180.html