gdbus 常用数据结构与库函数

常用数据结构

在 GDBus(基于 D-Bus 的通信框架)中,最常用的数据类型主要是通过 GVariant 来表示的。GVariant 是 GLib 提供的一种用于存储任意复杂数据结构的容器类型,它支持多种基础数据类型以及嵌套结构。以下是 GDBus 中最常用的一些数据类型及其对应的 D-Bus 类型代码:

基础数据类型

  1. BYTE (y)

    • GLib 数据类型 : guchar
    • 描述: 无符号8位整数 (0-255)
  2. BOOLEAN (b)

    • GLib 数据类型 : gboolean
    • 描述 : 布尔值,通常为 TRUEFALSE
  3. INT16 (n)

    • GLib 数据类型 : gint16
    • 描述: 有符号16位整数 (-32768到32767)
  4. UINT16 (q)

    • GLib 数据类型 : guint16
    • 描述: 无符号16位整数 (0到65535)
  5. INT32 (i)

    • GLib 数据类型 : gint32
    • 描述: 有符号32位整数 (-2^31 到 2^31 - 1)
  6. UINT32 (u)

    • GLib 数据类型 : guint32
    • 描述: 无符号32位整数 (0到4294967295)
  7. INT64 (x)

    • GLib 数据类型 : gint64
    • 描述: 有符号64位整数
  8. UINT64 (t)

    • GLib 数据类型 : guint64
    • 描述: 无符号64位整数
  9. DOUBLE (d)

    • GLib 数据类型 : gdouble
    • 描述: 双精度浮点数
  10. STRING (s)

    • GLib 数据类型 : gchar*
    • 描述: UTF-8 编码的字符串

复杂数据类型

  1. ARRAY (a)

    • 示例 : ai 表示一个整数数组
    • 描述: 包含相同类型的元素集合
  2. VARIANT (v)

    • 描述: 可以包含任何其他类型的变体值
  3. DICTIONARY (a{sv}a{ss} 等)

    • 示例 : a{ss} 表示键和值都是字符串的字典
    • 描述: 键值对的集合,其中键通常是字符串,值可以是任意类型
  4. STRUCTURE (r 或括号形式如 (ii) )

    • 示例 : (is) 表示一个整数和一个字符串组成的结构
    • 描述: 固定顺序的多个值的组合

示例

创建一个简单的 GVariant
c 复制代码
// 创建一个 INT32 类型的 GVariant
GVariant *variant = g_variant_new_int32(42);

// 创建一个 STRING 类型的 GVariant
GVariant *string_variant = g_variant_new_string("Hello, World!");

// 创建一个 ARRAY 类型的 GVariant
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
g_variant_builder_add(&builder, "i", 1);
g_variant_builder_add(&builder, "i", 2);
g_variant_builder_add(&builder, "i", 3);
GVariant *array_variant = g_variant_builder_end(&builder);
使用 GVariant 在 D-Bus 方法调用中传递参数

假设你有一个 D-Bus 接口方法 AddNumbers 需要接收两个整数并返回它们的和:

xml 复制代码
<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>

你可以这样实现客户端调用:

c 复制代码
gint num1 = 5, num2 = 7;
gint sum;
com_example_calculator_call_add_numbers_sync(proxy, num1, num2, &sum, NULL, &error);
if (!error) {
    g_print("Sum: %d\n", sum);
}

而在服务端处理该方法时,可以通过 GVariant 获取输入参数,并设置输出参数:

c 复制代码
static void handle_add_numbers(ComExampleCalculator *object, GDBusMethodInvocation *invocation, gint num1, gint num2) {
    gint sum = num1 + num2;
    com_example_calculator_complete_add_numbers(object, invocation, sum);
}

常用库函数

在使用 GDBus 进行开发时,有几个关键的库函数和工具是经常使用的。这些函数主要用于创建和管理 D-Bus 连接、注册对象、调用远程方法、处理信号等。以下是一些最常用的 GDBus 库函数及其简要说明:

1. 建立连接

  • g_bus_get_sync() : 同步获取一个 D-Bus 连接。

    c 复制代码
    GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
    • G_BUS_TYPE_SESSION: 表示会话总线。
    • NULL: 取消操作的上下文(Cancellable)。
    • &error: 错误信息。

2. 注册对象到 D-Bus 上

  • g_dbus_interface_skeleton_export() : 将接口骨架导出到 D-Bus 上。

    c 复制代码
    gboolean success = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(service), connection, "/com/example/calculator", &error);
    • G_DBUS_INTERFACE_SKELETON(service): 要导出的服务实例。
    • connection: D-Bus 连接。
    • "/com/example/calculator": 对象路径。
    • &error: 错误信息。

3. 创建代理对象

  • com_example_calculator_proxy_new_sync() : 创建一个新的代理对象,用于与远程服务进行通信。

    c 复制代码
    ComExampleCalculator *proxy = com_example_calculator_proxy_new_sync(connection, G_DBUS_PROXY_FLAGS_NONE, "com.example.Calculator", "/com/example/calculator", NULL, &error);

4. 调用远程方法

  • com_example_calculator_call_add_numbers_sync() : 同步调用远程方法。

    c 复制代码
    gboolean success = com_example_calculator_call_add_numbers_sync(proxy, num1, num2, &result, NULL, &error);
    • proxy: 代理对象。
    • num1, num2: 输入参数。
    • &result: 输出结果。
    • NULL: 取消操作的上下文(Cancellable)。
    • &error: 错误信息。

5. 发送信号

  • com_example_calculator_emit_status_update() : 发送信号通知客户端。

    c 复制代码
    com_example_calculator_emit_status_update(object, "Calculation completed.");

6. 处理信号

  • g_signal_connect() : 连接信号处理函数。

    c 复制代码
    g_signal_connect(proxy, "status-update", G_CALLBACK(on_status_update), NULL);
    • proxy: 代理对象。
    • "status-update": 信号名称。
    • G_CALLBACK(on_status_update): 回调函数。
    • NULL: 用户数据。

7. 使用 GVariant 构建复杂数据结构

  • g_variant_builder_new(): 创建一个新的变体构建器。

    c 复制代码
    GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("av"));
    • G_VARIANT_TYPE("av"): 指定构建器类型为数组(a)中的变体(v)。
  • g_variant_builder_add(): 添加元素到构建器中。

    c 复制代码
    g_variant_builder_add(builder, "{ss}", "location", "file:///tmp/00000001/1.mp3");
  • g_variant_builder_end(): 完成构建并生成 GVariant 对象。

    c 复制代码
    GVariant *playlist = g_variant_builder_end(builder);

8. 序列化与反序列化

  • g_variant_new_from_data(): 根据二进制数据创建 GVariant 对象。

    c 复制代码
    GVariant *playlist = g_variant_new_from_data(G_VARIANT_TYPE("av"), data, size, TRUE, NULL, NULL);
    • G_VARIANT_TYPE("av"): 数据类型。
    • data: 二进制数据。
    • size: 数据大小。
    • TRUE: 是否信任数据来源。
  • g_variant_iter_new(): 创建一个新的迭代器用于遍历 GVariant 数组。

    c 复制代码
    GVariantIter *iter = g_variant_iter_new(playlist);
  • g_variant_iter_next(): 遍历 GVariant 数组中的下一个元素。

    c 复制代码
    while (g_variant_iter_next(iter, "v", &item)) {
        // 处理每个 item
    }
相关推荐
果子⌂1 小时前
容器技术入门之Docker环境部署
linux·运维·docker
深度学习04072 小时前
【Linux服务器】-安装ftp与sftp服务
linux·运维·服务器
iteye_99393 小时前
让 3 个线程串行的几种方式
java·linux
渡我白衣3 小时前
Linux操作系统:再谈虚拟地址空间
linux
阿巴~阿巴~4 小时前
Linux 第一个系统程序 - 进度条
linux·服务器·bash
DIY机器人工房4 小时前
代码详细注释:通过stat()和lstat()系统调用获取文件的详细属性信息
linux·嵌入式
望获linux5 小时前
【Linux基础知识系列】第四十三篇 - 基础正则表达式与 grep/sed
linux·运维·服务器·开发语言·前端·操作系统·嵌入式软件
眠りたいです5 小时前
Mysql常用内置函数,复合查询及内外连接
linux·数据库·c++·mysql
我的泪换不回玫瑰5 小时前
Linux系统管理命令
linux
jjkkzzzz6 小时前
Linux下的C/C++开发之操作Zookeeper
linux·zookeeper·c/c++