【Linux dbus】2-dbus发送消息(以创建方法调用为例)的过程

news/2025/11/6 3:23:57/文章来源:https://www.cnblogs.com/FBsharl/p/19195024

消息(方法调用)创建后的典型流程

仅仅创建消息头是不够的,完整的调用流程如下:

  1. 创建方法调用消息 - dbus_message_new_method_call

  2. 添加参数 - dbus_message_append_args

  3. 发送消息 - dbus_connection_send

  4. (可选)等待并获取回复 - dbus_connection_send_with_reply_and_block

同系列类似函数的对比

为了更好地理解,这里有几个相关的函数:

 
函数 用途 类比
dbus_message_new_method_call 创建方法调用(客户端) 写一封请求信:"请执行X方法"
dbus_message_new_signal 创建信号消息 发一个广播通知:"某事件发生了"
dbus_message_new_method_return 创建方法回复(服务端) 回信:"方法执行结果是这样"
dbus_message_new_error 创建错误回复(服务端) 回信:"执行出错了"

 

使用示例

让我们通过几个具体例子来理解:

示例1:调用一个无参数的方法

// 让VLC播放器开始播放
DBusMessage *message = dbus_message_new_method_call("org.mpris.MediaPlayer2.vlc",  // 目标服务"/org/mpris/MediaPlayer2",     // 对象路径"org.mpris.MediaPlayer2.Player", // 接口"Play"                         // 方法名
);if (message == NULL) {fprintf(stderr, "创建消息失败:内存不足\n");return;
}// 发送消息(不等待回复)
dbus_connection_send(connection, message, NULL);
dbus_message_unref(message);  // 重要:释放消息

示例2:调用带参数的方法

// 调用计算器服务的加法方法:Add(10, 20)
DBusMessage *message = dbus_message_new_method_call("com.example.Calculator","/com/example/Calculator","com.example.Calculator.Basic","Add"
);if (message == NULL) {fprintf(stderr, "创建消息失败\n");return;
}// 添加参数
dbus_uint32_t a = 10, b = 20;
if (!dbus_message_append_args(message,DBUS_TYPE_UINT32, &a,DBUS_TYPE_UINT32, &b,DBUS_TYPE_INVALID)) {fprintf(stderr, "添加参数失败\n");dbus_message_unref(message);return;
}// 发送并等待回复
DBusError error;
dbus_error_init(&error);
DBusMessage *reply = dbus_connection_send_with_reply_and_block(connection, message, 1000, &timeout, &error  // 1秒超时
);if (dbus_error_is_set(&error)) {fprintf(stderr, "调用失败: %s\n", error.message);dbus_error_free(&error);
} else if (reply) {// 处理回复...dbus_message_unref(reply);
}dbus_message_unref(message);

示例3:调用设置属性值的方法

// 设置音量:SetVolume(0.8)
DBusMessage *message = dbus_message_new_method_call("org.mpris.MediaPlayer2.vlc","/org/mpris/MediaPlayer2","org.freedesktop.DBus.Properties","Set"  // 标准的Properties接口的Set方法
);if (message) {const char *interface = "org.mpris.MediaPlayer2.Player";const char *property_name = "Volume";double volume = 0.8;DBusMessageIter iter, sub;dbus_message_iter_init_append(message, &iter);// 参数是:接口名,属性名,属性值dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property_name);// 属性值需要包装为variant类型dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "d", &sub);dbus_message_iter_append_basic(&sub, DBUS_TYPE_DOUBLE, &volume);dbus_message_iter_close_container(&iter, &sub);// 发送消息...dbus_connection_send(connection, message, NULL);dbus_message_unref(message);
}

 

核心概念

dbus_message_new_method_call 是用于创建一个D-Bus方法调用消息的函数。简单来说,它就是用来构造一个"请求包",让你能够调用另一个D-Bus服务提供的方法

可以把D-Bus通信想象成远程过程调用(RPC):

  • 服务端:提供各种方法(比如 PlayPauseGetVolume

  • 客户端:需要调用这些方法

  • dbus_message_new_method_call:就是客户端用来"写调用请求"的工具


函数原型

c
 
 
DBusMessage * dbus_message_new_method_call(const char *service,const char *path,const char *interface,const char *method);

参数详解

这四个参数共同确定了"要调用谁的方法":

  1. service (const char *)

    • 目标服务的众所周知名称。这就是对方通过 dbus_bus_request_name 注册的名称。

    • 示例"org.mpris.MediaPlayer2.vlc""com.example.CalculatorService"

  2. path (const char *)

    • 对象路径。在D-Bus中,一个服务可以暴露多个对象,每个对象有唯一的路径,类似于文件系统路径。

    • 示例"/org/mpris/MediaPlayer2""/com/example/Calculator"

    • 通常以反向DNS格式组织。

  3. interface (const char *)

    • 接口名称。一个对象可以实现多个接口,每个接口包含一组相关的方法和信号。

    • 示例"org.mpris.MediaPlayer2.Player""com.example.Calculator.Basic"

    • 这相当于编程中的接口或类名。

  4. method (const char *)

    • 要调用的具体方法名

    • 示例"Play""Pause""Add""GetProperty"


返回值

  • 成功:返回一个指向新创建的 DBusMessage 对象的指针。

  • 失败:返回 NULL(通常是因为内存不足)。

重要:返回的消息对象已经过引用计数,使用完后必须用 dbus_message_unref 释放。

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

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

相关文章

CSP-S 2025 复赛解析

刚写完,暂时只放了代码,具体思路争取在7号晚上补完[CSP-S 2025] 社团招新 / club 题目描述 小 L 是学校算法协会的成员。在今年的学校社团招新中,小 L 一共招收了 \(n\) 个新成员,其中 \(n\) 为偶数。现在小 L 希望…

记录一次Prism9隐式注册引发的事件聚合器失效问题

直接上代码 1、我的注册从App的RegisterTypes方法迁移到了模块public class AccountModule : IModule{public void OnInitialized(IContainerProvider containerProvider){}public void RegisterTypes(IContainerRegis…

20232318 2025-2026-1 《网络与系统攻防技术》实验四实验报告

一、实验内容 本次实验围绕恶意代码分析的核心流程展开,具体包含四项关键任务:一是识别恶意代码的文件类型标识,完成文件脱壳操作与字符串提取,为后续分析扫清障碍;二是运用 IDA Pro 工具对指定 exe 文件开展静态…

用友U8C销售订单开单比较慢

1.登录软件录SPRso_accountmany_m比较耗时 2.检查so_accountmany_m的索引SELECTa.uniqueness 索引类型,b.index_name 索引名称,b.column_name 字段,a.table_name 表名 FROMuser_indexes a ,user_ind_columns b WHEREa.…

Winfrom机器人自动寻路

Winfrom机器人自动寻路public partial class Form1 : Form{private const int MapWidth = 25;private const int MapHeight = 20;private const int CellSize = 50;private List<Obstacle> obstacles = new List…

低代码平台基础知识

1.数据导入 在数据源将数据库下的物理表导入为数据模型 新建 → 数据库表模型 → 搜索 → 导入目录 一 连接方式(实时连接/只读模式/读写模式) 2.空白模型 使用空白模型定义表结构 新建 → 空白模型 切换到字段列表 →…

test first

记录第一次使用 简单写一点内容看看效果展示 展示

Win11 install CUDA 12.5

1.Check pc supported Nvidia GPUnvidia-smi 2.Download CUDA12.5https://developer.download.nvidia.cn/compute/cuda/12.5.0/local_installers/cuda_12.5.0_555.85_windows.exe3.Install CUDA12.5//validate nvcc --…

机器学习-逻辑回归算法-向量版代码

`import numpy as np x_train=[[1,2],[1,3],[1,6],[1,9],[1,2],[1,3],[1,6],[1,9]] y_train=[1,1,0,0,1,1,0,0] x_train_num=len(x_train) 向量化训练组 x_a=np.array(x_train) x_v=(x_a.T) y_v=np.array(y_train) pri…

星期三

今天离散和马原感觉没啥意思。早上第1节课太困了。睡着了。

「学习笔记」文件包含

文件包含开发人员常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程就叫做包含。文件包含漏洞 通常出现在动态网页中,有时候由于网站功能需求,会让前端用户选…

【AI说Rust 03】如何在 macos m1 系统搭建 rust 开发环境

在 macOS M1 上搭建 Rust 开发环境非常直接,主要依赖于官方工具 rustup。下面我为你梳理了一份清晰的步骤指南,包含一些实用技巧。 🔧 安装步骤概览 首先,我们来快速了解核心步骤:步骤 关键操作/命令 说明1. 安装…

厨房小白学做饭——4.干锅菜花

1.将菜花掰成朵,倒入清水,少加入一些盐,泡10分钟左右; 2.切一些五花肉备用【五花肉去皮】,切成片,薄厚均匀就行; 3.将线椒切成丝【建议红绿都来点,好看一些】,也可用小米椒切丝,再来四五瓣蒜,拍一下; 4.锅…

操盘计划202511090017

好的,我们来整合信息,直接回答您的两个核心问题。 问题一:哪几只股票重复次数最高? 这里的“重复次数”指的是在所有模型(xgb, lr, rf, svr)和所有预测时间点的综合预测中,同一只股票出现的总次数。次数越高,说…

Effective C++

条款01:视C++为一个语言联邦多重范型编程语言,在某个次语言中,各种高效编程守则简单易懂;但从一个语言移到另一个语言,守则可能改变。 次语言类型:C: Object-Oriented C++: Template C++: STL:条款02: 尽量以co…

厨房小白学做饭——3.虎皮青椒

1.螺丝椒洗好控干水分,同时准备几瓣大蒜,拍一下然后剁碎; 2.去除辣椒籽,将辣椒拍一下,然后切成小段; 3.起锅加油,油热后放入辣椒,用铲子按压,使辣椒受热均匀【火不要开的太大,容易把辣椒炒焦】,边按压边翻炒…

20251105 之所思 - 人生如梦

20251105 之所思今天做的好的事情:1. 主动汇报 和直接上级有一个两周一次半小时的会议,汇报SW这边的一些状态和数据,今天可能是升职以来第一次正式的主动汇报,以前虽然会议是book了,但是每次都是因为老板的时间导…

【Kubernetes】入门-部署Spring应用

Kubernetes 基本概念 Pod 是什么: Kubernetes 中最小的、最简单的部署和管理单元。 类比: 一台“逻辑主机”或一个“虚拟机实例”。 关键点:一个 Pod 可以包含一个或多个紧密相关的容器(例如,一个应用容器和一个日…

第16天(简单题中等题 二分查找)

打卡第十六天 4道简单题+1道中等题 耗时≈一小时 明天继续

Java项目常用异常处理场景与实战指南

在Java开发中,异常处理直接决定了系统的健壮性和可维护性。不合理的处理方式可能导致系统崩溃、数据丢失或调试困难,而规范的处理能让系统在异常场景下优雅降级。本文结合实际项目经验,梳理高频异常场景及解决方案,…