【d-bus】gdbus-codegen 使用教程

news/2025/11/14 1:07:03/文章来源:https://www.cnblogs.com/FBsharl/p/19220026

参考文章:https://blog.csdn.net/qq_40650634/article/details/149168037

 

基本概念与编程教程参考一下文章

1.Gdbus 的编程教程:https://blog.csdn.net/adlindary/article/details/80167840

2.DBUS 基础概念:https://blog.csdn.net/yishuige/article/details/52852531

3.DBUS 性能优化-数据的序列化:https://blog.csdn.net/coroutines/article/details/38496145

使用 gdbu-codegen 的好处

使用 gdbus-codegen 工具根据定义的接口 XML 文件生成 .c 和 .h 文件,是利用 GDBus 进行进程间通信(IPC)编程的一种常见做法。这种做法有以下几个主要好处:

1. 简化编码工作

手动编写 D-Bus 方法调用、信号处理等代码不仅繁琐,而且容易出错。通过 gdbus-codegen 自动生成这些代码,可以显著减少开发者的负担,让他们能够专注于业务逻辑的实现而非底层通信细节。

2. 提高代码的一致性和准确性

自动生成的代码遵循 D-Bus 规范和最佳实践,这有助于确保不同模块之间的交互是一致且准确的。开发者不需要担心因为手写的错误而导致的协议不匹配问题。

3. 增强可维护性

当需要修改或扩展 D-Bus 接口时,只需更新 XML 接口描述文件,然后重新运行 gdbus-codegen 即可轻松地生成新的 C 源文件和头文件。这种方式使得代码更加易于维护,减少了由于手动修改带来的风险。

4. 促进模块化设计

将接口定义从具体的实现中分离出来,有利于构建松耦合的系统架构。服务端和客户端都可以依赖于相同的接口定义,这样即使两端的具体实现发生变化,只要接口不变,双方仍然可以无缝协作。

5. 支持异步操作

GDBus 支持异步方法调用和信号发送,而 gdbus-codegen 生成的代码通常会包含对这些特性的支持,使开发者能够更容易地编写高效、响应迅速的应用程序。

6. 便于团队协作

对于大型项目或者多个开发者共同参与的项目来说,有一个清晰的接口定义可以让团队成员更清楚地了解系统的各个部分是如何交互的,从而提高团队的工作效率。

实践中的应用

假设我们要开发一个服务端和客户端应用,其中服务端提供一个方法用于加法运算,并能通过信号通知客户端当前的服务状态。

示例场景

  • 服务端:提供一个名为 AddNumbers 的方法,接收两个整数作为输入参数,返回它们的和。
  • 客户端:调用服务端的 AddNumbers 方法,并监听服务端发送的状态更新信号。

步骤 1: 定义 D-Bus 接口 XML 文件

首先,我们需要定义一个接口描述文件(例如 example.xml),用于描述服务的方法和信号:

<?xml version="1.0" encoding="UTF-8"?>
<node name="/com/example/calculator"><interface name="com.example.Calculator"><!-- 提供加法运算 --><method name="AddNumbers"><arg type="i" name="num1" direction="in"/><arg type="i" name="num2" direction="in"/><arg type="i" name="sum" direction="out"/></method><!-- 服务状态更新信号 --><signal name="StatusUpdate"><arg type="s" name="message"/></signal></interface>
</node>

步骤 2: 使用 gdbus-codegen 生成代码

接下来,利用 gdbus-codegen 根据上述 XML 文件生成 C 语言的代码框架:

gdbus-codegen --generate-c-code=calculator example.xml

这将生成 calculator.c 和 calculator.h 文件,这些文件包含了与 D-Bus 接口交互所需的所有函数原型和数据结构定义。

步骤 3: 实现服务端逻辑

在服务端实现中,我们将导入生成的头文件,并编写处理 AddNumbers 方法和发送 StatusUpdate 信号的具体逻辑:

#include "calculator.h"
#include <gio/gio.h>// 处理 AddNumbers 方法的回调函数
static void handle_add_numbers(ComExampleCalculator *object, GDBusMethodInvocation *invocation, gint num1, gint num2) {gint sum = num1 + num2;g_print("Adding %d and %d results in %d\n", num1, num2, sum);// 完成方法调用并返回结果com_example_calculator_complete_add_numbers(object, invocation, sum);// 发送状态更新信号给所有监听的客户端com_example_calculator_emit_status_update(object, "Calculation completed.");
}int main() {GMainLoop *loop = g_main_loop_new(NULL, FALSE);GError *error = NULL;// 创建服务对象实例ComExampleCalculator *service = com_example_calculator_skeleton_new();// 连接 handle_add_numbers 函数到 AddNumbers 方法g_signal_connect(service, "handle-add-numbers", G_CALLBACK(handle_add_numbers), NULL);// 获取会话总线连接GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);if (connection == NULL) {g_printerr("Failed to connect to the bus: %s\n", error->message);return 1;}// 将服务对象导出到 D-Bus 上g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(service), connection, "/com/example/calculator", &error);if (error != NULL) {g_printerr("Failed to export object: %s\n", error->message);return 1;}g_print("Service is running...\n");// 启动主事件循环g_main_loop_run(loop);return 0;
}
  • handle_add_numbers:这是处理客户端调用 AddNumbers 方法的回调函数。它计算两个数字的和,并通过 com_example_calculator_complete_add_numbers() 返回结果。同时,它还会发送一个 StatusUpdate 信号告知客户端操作已完成。
  • main 函数:
    创建了一个 GMainLoop 实例,用于运行主事件循环。
    使用 com_example_calculator_skeleton_new() 创建了一个新的服务骨架对象。
    使用 g_signal_connect() 将 handle_add_numbers 函数与 AddNumbers 方法绑定。
    使用 g_bus_get_sync() 获取会话总线(session bus)连接。
    最后,使用 g_dbus_interface_skeleton_export() 将服务对象导出到指定的路径 /com/example/calculator 上。

步骤 4: 实现客户端逻辑

客户端需要连接到服务端,调用 AddNumbers 方法,并监听 StatusUpdate 信号:

#include "calculator.h"
#include <gio/gio.h>// 状态更新信号的处理函数
static void on_status_update(ComExampleCalculator *proxy, const gchar *message, gpointer user_data) {g_print("Received status update: %s\n", message);
}int main() {GError *error = NULL;// 获取会话总线连接GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);if (connection == NULL) {g_printerr("Failed to connect to the bus: %s\n", error->message);return 1;}// 创建代理对象ComExampleCalculator *proxy = com_example_calculator_proxy_new_sync(connection, G_DBUS_PROXY_FLAGS_NONE, "com.example.Calculator", "/com/example/calculator", NULL, &error);if (proxy == NULL) {g_printerr("Failed to create proxy: %s\n", error->message);return 1;}// 连接信号处理函数g_signal_connect(proxy, "status-update", G_CALLBACK(on_status_update), NULL);// 调用远程方法gint result;gboolean success = com_example_calculator_call_add_numbers_sync(proxy, 5, 7, &result, NULL, &error);if (!success) {g_printerr("Failed to call AddNumbers: %s\n", error->message);return 1;}g_print("Result of AddNumbers: %d\n", result);return 0;
}
  • on_status_update:这是一个信号处理函数,每当服务端发出 StatusUpdate 信号时,该函数会被调用,并打印接收到的消息。
  • main 函数:
    首先获取会话总线连接。
    使用 com_example_calculator_proxy_new_sync() 创建一个代理对象,这个对象允许客户端像调用本地方法一样调用远程服务的方法。
    使用 g_signal_connect() 将 on_status_update 函数与 StatusUpdate 信号绑定。
    调用 com_example_calculator_call_add_numbers_sync() 来同步调用服务端的 AddNumbers 方法,并打印返回的结果。

总结

通过这个简单的例子,我们可以看到:

  • 简化编码工作:手动编写 D-Bus 方法调用和信号处理非常复杂,而 gdbus-codegen 自动生成了必要的函数原型和数据结构。
  • 提高代码的一致性和准确性:自动生成的代码遵循标准规范,减少了人为错误。
  • 增强可维护性:如果需要修改或扩展接口,只需更新 XML 文件并重新生成代码即可。
  • 支持异步操作:虽然本例中使用的是同步调用,但生成的代码也支持异步操作,便于构建高效的应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/964866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

logstash配置和启动

第二步:配置 Logstash(接收 Filebeat 日志,处理后发送到 Elasticsearch) 1. 创建 Logstash 管道配置文件 进入 Logstash 安装目录的 config 文件夹(如 C:\logstash-9.2.1\config),新建一个文件 springcloud-pip…

最近改论文的诡异经历…… - BUAA

事情是这样的: 昨晚凌晨两点,我还在和论文死磕。 不是不想睡,是查重率死活压不下去,知网报告上那一片标红看着像案发现场。 室友早就躺平,鼾声如雷。我盯着屏幕,脑子已经不会转了,复制粘贴了一堆“智能降重”网…

newDay21

1.背背单词,把u校园和英语ppt弄了,再写写离散数学 2.还差一堆任务,看看能弄多少弄多少吧 3.没啥问题

2025广东封闭式管理学校最新TOP5评测:重塑少年言行,见证成长蜕变

随着青少年心理健康与综合素质培养需求的持续攀升,封闭式管理教育机构已成为解决青少年成长问题的重要力量。本榜单基于安全管理规范、课程专业度、心理干预能力、家长满意度四大核心维度,结合行业协会实地走访与第三…

2025年广东军事化训练学校/机构最新TOP5权威评测:铸就坚毅品格,领航成长之路

随着社会对青少年综合素质培养的重视,军事化训练作为塑造品格、提升能力的重要途径,市场需求持续攀升。本榜单基于技术特色、课程体系、实战效果、家长口碑四大维度,结合行业调研数据与用户反馈,精选广东地区五家实…

2025年广东青少年感恩教育学校/机构最新TOP5推荐:家庭教育、心理健康,科学评测

随着青少年心理健康与家庭关系问题日益受到社会关注,专业的感恩教育与家庭教育机构成为家庭改善亲子关系、引导孩子健康成长的重要选择。本榜单基于教育资质、课程体系、师资力量、实践效果四大核心维度,结合广东省教…

2025广东法制教育机构/学校最新TOP5评测:心理健康、素质拓展、行为矫正全覆盖

随着青少年法治意识培养成为社会教育重点,专业法制教育机构的选择备受家长关注。本榜单基于教学资质、课程体系、师资力量、硬件设施四大核心维度,结合广东省教育厅备案信息及家长口碑数据,权威解析2025年广东地区五…

2025年广东青少年素质拓展训练学校最新TOP5实力榜:以规范养习惯,护航成长之路

随着青少年心理健康与综合素质教育需求的不断攀升,专业素质拓展训练机构成为教育市场的重要力量。本榜单基于基地规模、资质认证、课程体系、转化效果四大核心维度,结合广东省教育厅备案信息及家长满意度调研数据,权…

2025年广东青少年行为矫正学校TOP5权威评测:科学矫正护航成长未来

随着青少年心理健康问题日益凸显,专业行为矫正机构成为家庭解决教育难题的重要选择。本榜单基于办学资质、矫正效果、师资力量、安全保障四大核心维度,结合广东省教育厅备案信息及家长真实反馈,深度解析2025年广东地…

高级程序语言设计第五次个人作业

这个作业属于哪个课程 <班级的链接>这个作业要求在哪里 <作业链接>学号 092300303姓名 池博洋@目录一、设计作业1.使得程序遇到空格符时结束2.文件重定向,小写转大写3. 四则运算计算器4.混合读入字符、数…

2025年贵州贵阳母婴护理机构最新TOP5评测:守护母婴健康的专业力量

随着母婴健康意识的提升,专业母婴护理机构成为新家庭的重要选择。本榜单基于环境设施、人员资质、服务质量、安全管理四大核心维度,结合行业服务标准与用户口碑数据,全面解析2025年贵阳五大母婴护理品牌综合实力,为…

2025贵州贵阳月子会所最新TOP5评测:产后恢复优选,守护母婴健康

随着现代家庭对产后护理需求的升级,专业月子会所已成为新生代父母的核心选择。本榜单基于服务专业性、环境设施、护理团队、客户口碑四大维度,结合《2025中国母婴护理行业发展报告》及本地宝妈真实评价,权威解析贵阳…

2025年贵州贵阳月子中心最新TOP5专业评测:守护母婴健康新标杆

随着母婴护理需求的精细化升级,贵阳月子中心市场呈现专业化、高端化发展趋势。本榜单基于服务资质、护理团队专业性、设施环境、客户口碑四大核心维度,结合行业最新标准与真实用户反馈,权威解析2025年贵州贵阳五大月…

Excel VBA 自定义排序

现有数据如下:此时,如果需要根据单元格底色来排序,红色在上,其次是黄色,最后是白色(其实是无底色)。那么代码如下: Sub te()Dim wbk As WorkbookDim sht As WorksheetDim last_row As IntegerDim iCounter As …

基于GWO灰狼优化的XGBoost序列预测算法matlab仿真

1.算法运行效果图预览 (完整程序运行后无水印)3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)................................................................ %最大迭代次数 paramters.maxiter …

2025广东住房公积金提取机构最新TOP5评测:因为正规,所以高效

在住房公积金提取需求日益增长的背景下,选择专业可靠的代办服务机构成为许多人高效解决公积金提取难题的关键。本榜单基于服务专业性、业务覆盖范围、客户满意度等核心维度,结合市场反馈与行业数据,对广东及周边地区…

2025广东公积金提取代办中介最新TOP5评测:高效引领行业合规标准

随着住房公积金在居民生活中的重要性日益凸显,公积金提取代办服务需求持续攀升。本榜单依据合规资质、服务覆盖范围、客户满意度及办理效率四大核心维度,结合行业权威数据与用户反馈,对广东地区公积金代办机构进行综…

2025年深圳公积金提取最新TOP5评测:专业高效合规,引领行业标准

随着社会经济的发展,公积金作为一项重要的住房保障制度,其提取需求日益增长。然而,公积金提取流程复杂、政策多变,让许多人感到困扰。专业的公积金提取服务机构应运而生,为大众提供便捷、高效的服务。本榜单基于机…

《Chrome 开发者工具:前端调试必备》

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。 find_if(begin, end, predicate):查找…