新手向-C接口调用dbus

devtools/2024/10/25 13:20:07/

工作需要用c接口调用dbus,在这里写篇博客记录一下。


1. 方案比较

用C接口调用dbus一般来说有3种方案,分别是libdbusGDBus(GIO的一部分)和sd-bus(systemd的一部分),以下比较了3种方案的优劣:

接口方案libdbusGDBussd-bus
api类型低层 C APIGLib 的高层封装系统级 C API
依赖关系需要dbus需要glib需要systemd
易用性复杂简单较简单
性能有少量开销

之前一直用的libdbus,不过太复杂了,维护成本高。

这次是在linux上使用,系统自带systemd,因此这次选择了sd-bus,简单且不需要额外的依赖。

2. sd-bus的使用

2.1 安装

sudo apt update
sudo apt install libsystemd-dev

2.2  Demo

// sd-bus的头文件
#include <systemd/sd-bus.h>   
#include <stdio.h>int main(int argc, char *argv[]) {sd_bus *bus = NULL;sd_bus_message *msg = NULL;sd_bus_error error = SD_BUS_ERROR_NULL;int ret;// 连接到system bus用sd_bus_open_system// session bus的话用sd_bus_open_userret = sd_bus_open_system(&bus);if (ret < 0) {fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-ret));return ret;}// 调用Reboot方法ret = sd_bus_call_method(bus,"org.freedesktop.login1",         // Service to contact"/org/freedesktop/login1",        // Object path"org.freedesktop.login1.Manager", // Interface name"Reboot",                         // Method to call&error,                             // No reply expected&msg,                             // Output messageNULL);                            // No input argumentsif (ret < 0) {fprintf(stderr, "Failed to call method: %s\n", strerror(-ret));sd_bus_unref(bus);return ret;}// 检查返回值int response = 0;// 假如返回值是int类型ret = sd_bus_message_read(msg, "i", &response); if (ret < 0) {fprintf(stderr, "Failed to read response: %s\n", strerror(-ret));} else {printf("Method returned response: %d\n", response);}// Cleanupsd_bus_message_unref(msg);sd_bus_unref(bus);return 0;
}

 简单介绍一下,使用sd-bus的核心接口只有3个,连接到总线,调用method,以及读取返回值

2.2.1 连接到总线

连接到总线的接口有3个,函数原型如下:

int sd_bus_open_system(sd_bus **ret);             
// 连接system bus
int sd_bus_open_user(sd_bus **ret);               
// 连接session bus
int sd_bus_default(sd_bus **ret);                 
// 先连接session bus,不可用再连接system bus
2.2.2 调用method

函数原型如下:

// sd_bus_call_method 函数原型
int sd_bus_call_method(sd_bus *bus,                  // 总线连接const char *destination,      // 目标服务名const char *path,             // 对象路径const char *interface,        // 接口名称const char *member,           // 方法名sd_bus_error *ret_error,      // 错误信息sd_bus_message **reply,       // 响应消息const char *types,            // 参数类型字符串...                          // 可变参数列表
);

调用带多个参数的method

// 调用带多个参数的method
ret = sd_bus_call_method(bus,"org.example.Service","/org/example/object","org.example.Interface","ComplexMethod",&error,&reply,"siay",          // string, int32, array of bytes"test",          // string参数42,              // int32参数3,               // 数组长度(uint8_t[]){1,2,3}); // byte数组/* 常用参数类型说明:* s: string (const char *)* u: uint32_t* i: int32_t* x: int64_t* t: uint64_t* b: boolean (int)* y: byte (uint8_t)* d: double* ay: array of bytes* as: array of strings* a{sv}: dictionary of string keys to variant values* v: variant* o: object path*/

调用带一个参数的method

    // 调用带参数的方法ret = sd_bus_call_method(bus,"org.freedesktop.systemd1",           // 服务"/org/freedesktop/systemd1",          // 路径"org.freedesktop.systemd1.Manager",   // 接口"GetUnit",                            // 方法&error,                               // 错误对象&reply,                               // 响应消息"s",                                  // 参数类型: 字符串"sshd.service");                      // 参数值
2.2.3 读取返回值

函数原型如下,第一个入参是调用method,引用传递返回的reply。

// sd_bus_message_read 函数原型
int sd_bus_message_read(sd_bus_message *m,    // 消息对象const char *types,    // 数据类型字符串...                   // 要读取的变量指针
);

读取多个返回值的示例如下:

int ret;
const char *str;
int32_t num;
uint8_t byte;
double dbl;// 读取基本类型:字符串、32位整数、字节、双精度浮点数
ret = sd_bus_message_read(m, "siyd",&str,    // 字符串&num,    // 32位整数&byte,   // 字节&dbl);   // 双精度浮点数

http://www.ppmy.cn/devtools/128693.html

相关文章

Vue学习记录之十三 自定义指令directive

一、自定义指令的方法 Vue中有v-if、v-for、v-show、v-model等一些内置指令,其实我们也可以通过directive来自定义组件,但是他属于破坏性的更新。 必须以vNameOfDirective 的形式来命名本地自定义指令,以使得他们可以在模版中直接使用, 标签名称:v-NameofDirective 定义格…

Sqlite3 操作笔记

一、 数据格式 支持数据格式 一般数据采用的固定的静态数据类型&#xff0c;而SQLite采用的是动态数据类型&#xff0c;会根据存入值自动判断。SQLite具有以下五种数据类型&#xff1a; 1.NULL&#xff1a;空值。 2.INTEGER&#xff1a;带符号的整型&#xff0c;具体取决有存…

智创 AI 新视界 -- AIGC 背后的深度学习魔法:从原理到实践

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

AI劳动力崛起:人将面临失业危机?

场景 第一眼看到这个网站的时候&#xff0c;AI员工官网&#xff08;好像是部署在美国&#xff09;&#xff0c;我觉得很好奇&#xff0c;真的可以让AI替代人类完成工作吗&#xff1f;替代到什么程度呢&#xff1f;能以自然语言直接驱动吗&#xff1f; 正好手上在做爬虫项目&am…

深度学习中的注意力机制:从基础到应用

深度学习中的注意力机制&#xff1a;从基础到应用 前言1. 注意力机制的起源2. 注意力机制的基本原理3. 注意力机制的发展3.1 自注意力机制&#xff08;Self-Attention&#xff09;3.2 多头注意力机制&#xff08;Multi-Head Attention&#xff09; 4. 注意力机制的代码实现5. 注…

MoCoOp: Mixture of Prompt Learning for Vision Language Models

文章汇总 当前的问题 1)数据集风格变化。 如图1所示&#xff0c;对于一个数据集&#xff0c;单个软提示可能不足以捕获数据中呈现的各种样式。同一数据集中的不同实例可能与不同的提示符兼容。因此&#xff0c;更**自然的做法是使用多个提示来充分表示这些变化**。 2)过拟合…

洞察数据之美:用可视化探索销售与温度的关系

目录 数据可视化1.气温数据可视化图片展示将最高和最低气温合并绘制折线图&#xff1a;将最高和最低气温合并绘制散点图&#xff1a; 2.销售数据可视化几种常见的销售数据可视化方法及其适用场景&#xff1a;图片展示通过热力图和堆叠柱状图的直观展示&#xff0c;可以得出以下…

Java爬虫:API数据界的“宝藏猎人”

亲爱的代码探险家们&#xff0c;今天咱们不聊那些让人头秃的bug&#xff0c;也不谈那些让人眼花的架构图。咱们来聊聊那些在代码世界里寻找宝藏的“宝藏猎人”——Java爬虫。 Java爬虫&#xff1a;API数据界的“宝藏猎人” 想象一下&#xff0c;你在代码的世界里&#xff0c;遇…