当前位置: 首页 > news >正文

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

参考文章: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.jsqmd.com/news/39801/

相关文章:

  • logstash配置和启动
  • 最近改论文的诡异经历…… - BUAA
  • newDay21
  • 2025广东封闭式管理学校最新TOP5评测:重塑少年言行,见证成长蜕变
  • 2025年广东军事化训练学校/机构最新TOP5权威评测:铸就坚毅品格,领航成长之路
  • 2025年广东青少年感恩教育学校/机构最新TOP5推荐:家庭教育、心理健康,科学评测
  • 2025广东法制教育机构/学校最新TOP5评测:心理健康、素质拓展、行为矫正全覆盖
  • 2025年广东青少年素质拓展训练学校最新TOP5实力榜:以规范养习惯,护航成长之路
  • 2025年广东青少年行为矫正学校TOP5权威评测:科学矫正护航成长未来
  • 高级程序语言设计第五次个人作业
  • 2025年贵州贵阳母婴护理机构最新TOP5评测:守护母婴健康的专业力量
  • gcc编译时满屏错误信息咋办?
  • 2025贵州贵阳月子会所最新TOP5评测:产后恢复优选,守护母婴健康
  • 2025年贵州贵阳月子中心最新TOP5专业评测:守护母婴健康新标杆
  • Excel VBA 自定义排序
  • 基于GWO灰狼优化的XGBoost序列预测算法matlab仿真
  • 2025广东住房公积金提取机构最新TOP5评测:因为正规,所以高效
  • 2025广东公积金提取代办中介最新TOP5评测:高效引领行业合规标准
  • 2025年深圳公积金提取最新TOP5评测:专业高效合规,引领行业标准
  • 《Chrome 开发者工具:前端调试必备》
  • 使用 vLLM 本地部署 Qwen3-Embedding-8B 模型并接入 Dify 完整指南 - yi
  • 《VS Code:高效编程的插件与配置》
  • 11.13 NOTE
  • 2025广州公积金提取服务最新TOP5权威评测:专业合规引领行业标杆
  • 用Rust 解析验证码:结合 Tesseract OCR 进行文本识别
  • 10.26 NOTE
  • 10.22 NOTE
  • 题解:CF2106D Flower Boy
  • 使用 Maven 内置的版本号(Version)统一控制功能
  • 使用 Maven 内置的版本号(Version)统一控制功能