DBUS入门与C编程

2023-05-16

https://blog.csdn.net/weixin_45566765/article/details/125028296

一、D-Bus简介

1. D-Bus是什么

D-Bus最主要的用途是在 Linux 桌面环境为进程提供通信,同时能将 Linux 桌面环境和 Linux 内核事件作为消息传递到进程。D-Bus(其中D原先是代表桌面“Desktop” 的意思),即:用于桌面操作系统的通信总线。

D-Bus的主要概念为总线,注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。

D-Bus是为Linux系统开发的进程间通信(IPC)和远程过程调用(RPC)机制,使用统一的通信协议来代替现有的各种IPC解决方案。D-Bus允许系统级进程(如:打印机和硬件驱动服务)和普通用户进程进行通信。

2. D-Bus特性

D-Bus使用一个快速的二进制消息传递协议,D-Bus协议的低延迟和低消耗特点适用于同一台机器的通信。D-Bus的规范目前由freedesktop.org项目定义,可供所有团体使用。

D-Bus不和低层的IPC直接竞争,比如sockets,shared memory或message queues。低层IPC有自己的特点,和D-Bus并不冲突。

与其他重量级的进程间通信技术不同,D-Bus是非事务的。D-Bus使用了状态以及连接的概念,比UDP等底层消息传输协议更“聪明”。但另一方面,D-Bus传送的是离散消息,与TCP协议将数据看做“流”有所不同。D-Bus支持点对点的消息传递以及广播/订阅式的通信。

总结如下:

1、D-BUS的协议是低延迟而且低开销的,设计小巧且高效,以便最小化传送时间。从设计上避免往返交互并允许异步操作。
2、协议是二进制的,而不是文本,排除序列化过程。
3、考虑了字节序问题。
4、易用性:按照消息而不是字节流来工作,并且自动地处理了许多困难的IPC问题,并且D-Bus库以可以封装的方式来设计,开发者可以使用框架里存在的对象/类型系统,而不用学习一种新的专用于IPC的对象/类型系统。
5、请求时启动服务以及安全策略。
6、支持多语言(C/C++/Java/C#/Python/Ruby),多平台(Linux/windows/maemo)。
7、采用C语言,而不是C++。 H、由于基本上不用于internet上的IPC,因此对本地IPC进行了特别优化。
8、提供服务注册,理论上可以进行无限扩展。
9、支持广播类型的通信。
10、带有异常处理的通用远程调用接口;

二、D-Bus架构

1. 结构层次

D-Bus进程间通信主要有三层架构:
1.底层接口层:主要是通过libdbus这个函数库,给予系统使用DBus的能力。

2.总线层:主 要Message bus daemon这个总线守护进程提供的,在Linux系统启动时运行,负责进程间的消息路由和传递,其中包括Linux内核和Linux桌面环境的消息传递。总线守护进程可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。

3.应用封装层:通过一系列基于特定应用程序框架将DBus的底层接口封装成友好的Wrapper库,供不同开发人员使用。比如libdbus-glib, libdbus-python.

2.系统总线和会话总线

在一台机器上总线守护有多个实例(instance)。这些总线之间都是相互独立的。
在这里插入图片描述

  • 一个持久的系统总线(system bus)

    它在引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。 它是桌面会话和操作系统的通信,这里操作系统一般而言包括内核和系统守护进程。 这种通道的最常用的方面就是发送系统消息,比如:插入一个新的存储设备;有新的网络连接;等等。

  • 还将有很多会话总线(session buses)‘
    普通进程创建,可同时存在多条。会话总线属于某个进程私有,它用于进程间传递消息。

三、D-Bus编程基础知识

1.address地址

使用d-bus的应用程序既可以是server也可以是client,server监听到来的连接,client连接到 server,一旦连接建立,消息就可以流转。点对点通信时就是一个 server 和 一个 client;如果使用dbus daemon,所有的应用程序都是client,bus daemon 是server,daemon监听所有的连接,应用程序初始化连接到daemon

dbus地址指明server将要监听的地方,client将要连接的地方,例如,地址:unix:path=/tmp/abcdef表明 server将在/tmp/abcdef路径下监听unix域的socket,client也将连接到这个socket。一个地址也可以指明是 TCP/IP的socket,或者是其他的。

当使用bus daemon时,libdbus会从环境变量中(DBUS_SESSION_BUS_ADDRESS)自动认识“会话daemon”的地址。如果是系统 daemon,它会检查指定的socket路径获得地址,也可以使用环境变量(DBUS_SESSION_BUS_ADDRESS)进行设定。

2. bus name 总线名字

当一个应用连接到 bus daemon,daemon 立即会分配一个名字给这个连接,称为 Unique Connection Name, 这个唯一标识的名字以冒号 “:” 开头,例如 :1.2,这个名字在 daemon 的整个生命周期是唯一的。

但是这种名字总是临时分配,无法确定的,也难以记忆,因此应用可以要求有另外一个公共名 well-known name 来对应这个唯一标识,就像我们使用域名来映射 IP地址一样。例如可以使用 org.fmddlmyy.Test 来映射 :1.2。这样我们就可以使用公共名连接到 DBus 服务。

3. 原生对象和对象路径

d-bus 的底层接口是没有这些对象的概念的,它提供的是一种叫对象路径(object path),用于让高层接口绑定到各个对象中去,允许远端应用程序指向它们。object path就像是一个文件路径,可以叫做 /org/kde/kspread/sheets/3/cells/4/5 等。

4. 接口 Interface

接口是一组方法和信号,每一个对象支持一个或者多个接口,接口定义一个对象实体的类型。 D-Bus使用简单的命名空间字符串来表示接口,例如 org.freedesktop.Introspectable。

5. Methods 和 Signals

每一个对象有两类成员:方法和信号:

  • 方法就是一个函数,具有有输入和输出;
  • 信号会被广播,感兴趣的对象可以处理这个 信号,同时信号中也可以带有相关的数据。

在 D-BUS 中有四种类型的消息:

1、方法调用(method call) # 在对象上执行一个方法
2、方法返回(method return) # 返回方法执行的结果
3、信号(signal) # 调用方法产生的异常
4、错误(error)# 通知指定的信号发生了,可以想象成“事件”。

要执行D-BUS对象的方法,您需要向对象发送一个方法调用消息。 它将完成一些处理(就是执行了对象中的Method,Method是可以带有输入参数的)并返回,返回消息或者错误消息。 信号的不同之处在于它们不返回任何内容:既没有“信号返回”消息,也没有任何类型的错误消息。

6. 总结:方法所需要的参数

要在指定的对象中调用指定的方法,需要知道的参数如下:
Address -> [Bus Name] -> Path -> Interface -> Method

bus name是可选的,除非是希望把消息送到特定的应用中才需要。interface也是可选的,有一些历史原因,DCOP不需要指定接口,因为DCOP在同一个对象中禁止同名的方法。

四、D-Bus运行环境

1. 运行环境安装

# 安装依赖
sudo apt-get install dbus
sudo apt-get install libgtk2.0-dev
sudo apt-get install libdbus-glib-1-dev
# 安装 D-Feet
sudo apt-get install d-feet

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

同时下载一个简单的 DBus 程序:链接,运行方法:

tar -zxvf hello-dbus3-0.1.tar.gz

# 编译
cd hello-dbus3-0.1/
./autogen.sh
./configure
make

# 运行
cd src
./example-service

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

运行 d-feet,打开 Session bus,找到 “org.fmddlmyy.Test” 连接名,这个链接就是我们刚刚运行的一个D-Bus程序:

在这里插入图片描述

在右侧展开栏我们会发现 org.fmddlmyy.Test.Basic 下有一个 Add 方法,我们点击它,输入 1,2,点击执行,可以看到给我们返回了结果:

在这里插入图片描述

通过上面的操作我们通过 d-feet 发起了一次 d-bus 请求。

2. dbus-send以及dbus-monitor

dbus提供了两个小工具:dbus-send和dbus-monitor。我们可以用dbus-send发送消息。用dbus-monitor监视总线上流动的消息。 让我们通过dbus-send发送消息来调用前面的Add方法,这时dbus-send充当了应用程序B。用dbus-monitor观察调用过程中的消息

保持上面的example-server运行,新建两个窗口一个运行dubs-monitor一个运行如下命令

dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.fmddlmyy.Test.Basic.Add int32:100 int32:999

 
 
 
 
  • 1
  • dbus-send的详细用法可以参阅手册。调用远程方法的一般形式是

    $ dbus-send [--system | --session] --type=method_call --print-reply --dest=连接名 对象路径 接口名.方法名 参数类型:参数值 参数类型:参数值
    
       
       
       
       
    • 1

    dbus-send支持的参数类型包括:string, int32, uint32, double, byte, boolea

dubs-monitor窗口返回的消息如下:

# 1、向 D-Bus Damon 发送Hello建立连接
method call time=1653831830.713656 sender=:1.97 -> destination=org.freedesktop.DBus serial=1 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=Hello
method return time=1653831830.713685 sender=org.freedesktop.DBus -> destination=:1.97 serial=1 reply_serial=1
   string ":1.97"
# 2、广播全局,指定名称的拥有者发生了变化 
signal time=1653831830.713696 sender=org.freedesktop.DBus -> destination=(null destination) serial=10 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
   string ":1.97"  # 名字
   string ""       # 拥有者原始名字
   string ":1.97"  # 拥有者现在名字
# 3、通知应用获得了指定名称的拥有权
signal time=1653831830.713712 sender=org.freedesktop.DBus -> destination=:1.97 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
   string ":1.97"
# 4、调用 Add 方法  
method call time=1653831830.714160 sender=:1.97 -> destination=org.fmddlmyy.Test serial=2 path=/TestObj; interface=org.fmddlmyy.Test.Basic; member=Add
   int32 123
   int32 456
# 5、Add 方法返回结果
method return time=1653831830.714310 sender=:1.95 -> destination=:1.97 serial=7 reply_serial=2
   int32 579
# 6、通知应用失去了指定名称的拥有权
signal time=1653831830.715690 sender=org.freedesktop.DBus -> destination=:1.97 serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
   string ":1.97"
# 7、广播全局,指定名称的拥有者发生了变化
signal time=1653831830.715717 sender=org.freedesktop.DBus -> destination=(null destination) serial=11 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
   string ":1.97"
   string ":1.97"
   string ""

 
 
 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

上述一次完整的 d-bus 通信的流程

3.Dbus通信流程总结

(1) 方法调用的一般流程:

1.使用不同语言绑定的dbus高层接口,都提供了一些代理对象,调用其他进程里面的远端对象就像是在本地进程中的调用一样。应用调用代理上的方法,代理将构造一个方法调用消息给远端的进程。
2.在DBUS的底层接口中,应用需要自己构造方法调用消息(method call message),而不能使用代理。
3.方法调用消息里面的内容有:目的进程的bus name,方法的名字,方法的参数,目的进程的对象路径,以及可选的接口名称。
4.方法调用消息是发送到bus daemon中的。
5.bus daemon查找目标的bus name,如果找到,就把这个方法发送到该进程中,否则,daemon会产生错误消息,作为应答消息给发送进程。
6. 目标进程解开消息,在dbus底层接口中,会立即调用方法,然后发送方法的应答消息给daemon。在dbus高层接口中,会先检测对象路径,接口, 方法名称,然后把它转换成对应的对象(如GObject,QT中的QObject等)的方法,然后再将应答结果转换成应答消息发给daemon。
7.bus daemon接受到应答消息,将把应答消息直接发给发出调用消息的进程。
8.应答消息中可以包容很多返回值,也可以标识一个错误发生,当使用绑定时,应答消息将转换为代理对象的返回值,或者进入异常

(2) 信号的一般流程:

1.当使用dbus底层接口时,信号需要应用自己创建和发送到daemon,使用dbus高层接口时,可以使用相关对象进行发送,如Glib里面提供的信号触发机制。
2.信号包含的内容有:信号的接口名称,信号名称,发送进程的bus name,以及其他参数。
3.任何进程都可以依据”match rules”注册相关的信号,daemon有一张注册的列表。
4.daemon检测信号,决定哪些进程对这个信号感兴趣,然后把信号发送给这些进程。
5.每个进程收到信号后,如果是使用了dbus高层接口,可以选择触发代理对象上的信号。如果是dbus底层接口,需要检查发送者名称和信号名称,然后决定怎么做。

五、DBUS编程

1. 通用代码介绍

(1)连接代码

首先,客户端必须要连接上 Dbus,一般来说,系统中会有一个 System Bus 和一个 Session Bus。其次,你需要在 Dbus 中注册一个名字,用于标识自己。为了简单起见,这里先不考虑重名的情况:

DBusError err;
DBusConnection* conn;
int ret;
// initialise the errors
dbus_error_init(&err);

// connect to the bus
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, “Connection Error (%s)\n”, err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
exit(1);
}
// request a name on the bus
ret = dbus_bus_request_name(conn, “test.method.server”,
DBUS_NAME_FLAG_REPLACE_EXISTING
, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, “Name Error (%s)\n”, err.message);
dbus_error_free(&err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
exit(1);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

一般来说,连接上 Dbus 和注册一个名称,应该是在程序最开始运行的时候就会进行的操作。

当然,在程序结束的时候,需要关闭掉与 Dbus 的连接。使用下面的函数:

dbus_connection_close(conn);

 
 
 
 
  • 1

(2) 发送信号(Sending Signal)

信号是一种广播的消息,你可以简单的发出一个信号,这样,所有连接在 DBus 总线上并注册了接受对应信号的进程,都会收到这个信号。

为了发出一个信号,需要的只是创建一个 DBusMessage 对象来代表信号,然后追加上一些需要发出的参数,就可以发向总线了。

发完之后还需要释放掉 Message。如果内存不足的话,这下面不少函数都会返回 false,所以一般情况下你都需要处理这些情况的返回值。

dbus_uint32_t serial = 0; // unique number to associate replies with requests
DBusMessage* msg;
DBusMessageIter args;

// create a signal and check for errors
msg = dbus_message_new_signal(“/test/signal/Object”, // object name of the signal
“test.signal.Type”, // interface name of the signal
“Test”); // name of the signal
if (NULL == msg)
{
fprintf(stderr, “Message Null\n”);
exit(1);
}

// append arguments onto signal
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
fprintf(stderr, “Out Of Memory!\n”);
exit(1);
}

// send the message and flush the connection
if (!dbus_connection_send(conn, msg, &serial)) {
fprintf(stderr, “Out Of Memory!\n”);
exit(1);
}
dbus_connection_flush(conn);

// free the message
dbus_message_unref(msg);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

(3) 调用方法(Call a Methond)

调用一个远程方法(remote method)与发送一个信号(sending a signal)是很类似的。需要创建一个 DBusMessage,然后通过注册在 DBus 上的名称指定发送的对象,追加相应的参数,但调用方法分为两种,一种是阻塞式的,另一种则可以异步调用。异步调用的时候会得到一个 DBusMessage* 的返回,从这个 DBusMessage 中可以获取一些返回的参数。

调用方法1

DBusMessage* msg;
DBusMessageIter args;
DBusPendingCall* pending;

msg = dbus_message_new_method_call(“test.method.server”, // target for the method call
“/test/method/Object”, // object to call on
“test.method.Type”, // interface to call on
“Method”); // method name
if (NULL == msg) {
fprintf(stderr, “Message Null\n”);
exit(1);
}

// append arguments
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) {
fprintf(stderr, “Out Of Memory!\n”);
exit(1);
}

// send message and get a handle for a reply
if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
fprintf(stderr, “Out Of Memory!\n”);
exit(1);
}
if (NULL == pending) {
fprintf(stderr, “Pending Call Null\n”);
exit(1);
}
dbus_connection_flush(conn);

// free message
dbus_message_unref(msg);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

调用方法2

bool stat;
dbus_uint32_t level;

// block until we receive a reply
dbus_pending_call_block(pending);

// get the reply message
msg = dbus_pending_call_steal_reply(pending);
if (NULL == msg) {
fprintf(stderr, “Reply Null\n”);
exit(1);
}
// free the pending message handle
dbus_pending_call_unref(pending);

// read the parameters
if (!dbus_message_iter_init(msg, &args))
fprintf(stderr, “Message has no arguments!\n”);
else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))
fprintf(stderr, “Argument is not boolean!\n”);
else
dbus_message_iter_get_basic(&args, &stat);

if (!dbus_message_iter_next(&args))
fprintf(stderr, “Message has too few arguments!\n”);
else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
fprintf(stderr, “Argument is not int!\n”);
else
dbus_message_iter_get_basic(&args, &level);

printf(“Got Reply: %d, %d\n”, stat, level);

// free reply and close connection
dbus_message_unref(msg);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

(4) 接收消息(Receiving a Signal)

接下来的两种操作是从总线读取消息并处理这些消息。

要接收一个消息,你首先需要告诉 DBus 你对什么样的消息感兴趣

// add a rule for which messages we want to see
dbus_bus_add_match(conn,
                   "type='signal',interface='test.signal.Type'",
                   &err); // see signals from the given interface
dbus_connection_flush(conn);
if (dbus_error_is_set(&err)) {
    fprintf(stderr, "Match Error (%s)\n", err.message);
    exit(1);
}

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后,进程就可以在一个循环中等待这类消息的发生了

/ loop listening for signals being emmitted
while (true) {
<span class="token comment">// non blocking read of the next available message</span>
<span class="token function">dbus_connection_read_write</span><span class="token punctuation">(</span>conn<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
msg <span class="token operator">=</span> <span class="token function">dbus_connection_pop_message</span><span class="token punctuation">(</span>conn<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// loop again if we haven't read a message</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token constant">NULL</span> <span class="token operator">==</span> msg<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// check if the message is a signal from the correct interface and with the correct name</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">dbus_message_is_signal</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token string">"test.signal.Type"</span><span class="token punctuation">,</span> <span class="token string">"Test"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token comment">// read the parameters</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_init</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Message has no arguments!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>DBUS_TYPE_STRING <span class="token operator">!=</span> <span class="token function">dbus_message_iter_get_arg_type</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Argument is not string!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
        <span class="token function">dbus_message_iter_get_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>args<span class="token punctuation">,</span> <span class="token operator">&amp;</span>sigvalue<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Got Signal with value %s\n"</span><span class="token punctuation">,</span> sigvalue<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// free the message</span>
<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

(5) 提供被远程调用的方法(Exposing a Method to be called)

在(3) 调用方法(Call a Methond)中,我们看到了调用一个远程方法,这节就是告诉我们怎么样提供一个方法让别的应用程序调用。用下面的程序,就可以把方法关联在那些提供给外部的方法上,并解析出相应的参数,最后构建一个消息返回给调用方法的应用程序。

远程调用的方法1

// loop, testing for new messages
while (true) {
    // non blocking read of the next available message
    dbus_connection_read_write(conn, 0);
    msg = dbus_connection_pop_message(conn);
<span class="token comment">// loop again if we haven't got a message</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token constant">NULL</span> <span class="token operator">==</span> msg<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// check this is a method call for the right interface and method</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">dbus_message_is_method_call</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token string">"test.method.Type"</span><span class="token punctuation">,</span> <span class="token string">"Method"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token function">reply_to_method_call</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> conn<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// free the message</span>
<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

远程调用方法2:

void reply_to_method_call(DBusMessage* msg, DBusConnection* conn)
{
    DBusMessage* reply;
    DBusMessageIter args;
    DBusConnection* conn;
    bool stat = true;
    dbus_uint32_t level = 21614;
    dbus_uint32_t serial = 0;
    char* param = "";
<span class="token comment">// read the arguments</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_init</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Message has no arguments!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>DBUS_TYPE_STRING <span class="token operator">!=</span> <span class="token function">dbus_message_iter_get_arg_type</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Argument is not string!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">else</span>
    <span class="token function">dbus_message_iter_get_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>args<span class="token punctuation">,</span> <span class="token operator">&amp;</span>param<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Method called with %s\n"</span><span class="token punctuation">,</span> param<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// create a reply from the message</span>
reply <span class="token operator">=</span> <span class="token function">dbus_message_new_method_return</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// add the arguments to the reply</span>
<span class="token function">dbus_message_iter_init_append</span><span class="token punctuation">(</span>reply<span class="token punctuation">,</span> <span class="token operator">&amp;</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_append_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>args<span class="token punctuation">,</span> DBUS_TYPE_BOOLEAN<span class="token punctuation">,</span> <span class="token operator">&amp;</span>stat<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Out Of Memory!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_append_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>args<span class="token punctuation">,</span> DBUS_TYPE_UINT32<span class="token punctuation">,</span> <span class="token operator">&amp;</span>level<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Out Of Memory!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// send the reply &amp;&amp; flush the connection</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_connection_send</span><span class="token punctuation">(</span>conn<span class="token punctuation">,</span> reply<span class="token punctuation">,</span> <span class="token operator">&amp;</span>serial<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Out Of Memory!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">dbus_connection_flush</span><span class="token punctuation">(</span>conn<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// free the reply</span>
<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>reply<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

2. 实例代码

(1) 客户端代码

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dbus/dbus.h>

DBusConnection init_bus()
{
DBusConnection connection;
DBusError err;
int ret;

<span class="token function">dbus_error_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//连接到dbus,建立一个连接,称为对象</span>
connection <span class="token operator">=</span> <span class="token function">dbus_bus_get</span><span class="token punctuation">(</span>DBUS_BUS_SESSION<span class="token punctuation">,</span> <span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_error_is_set</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"connection error: :%s -- %s\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>name<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">dbus_error_free</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
    <span class="token comment">//为这个对象分配一个名字</span>
ret <span class="token operator">=</span> <span class="token function">dbus_bus_request_name</span><span class="token punctuation">(</span>connection<span class="token punctuation">,</span> <span class="token string">"hello.world.client"</span><span class="token punctuation">,</span> DBUS_NAME_FLAG_REPLACE_EXISTING<span class="token punctuation">,</span> <span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_error_is_set</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Name error: %s -- %s\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>name<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">dbus_error_free</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>ret <span class="token operator">!=</span> DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER<span class="token punctuation">)</span>
	<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

<span class="token keyword">return</span> connection<span class="token punctuation">;</span>

}

void send_signal(DBusConnection connection)
{
DBusMessage msg;
DBusMessageIter arg;
char *str = “hello world!”;

<span class="token comment">//创建一个signal对象</span>
<span class="token comment">//param1: path (这个逻辑来说,可以是任何字符串,只要符合规则即可)</span>
<span class="token comment">//param2: interface (一样)</span>
<span class="token comment">//param3: 信号方法名(必须与服务端名匹配)</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>msg <span class="token operator">=</span> <span class="token function">dbus_message_new_signal</span><span class="token punctuation">(</span><span class="token string">"/hello"</span><span class="token punctuation">,</span> <span class="token string">"aa.bb.cc"</span><span class="token punctuation">,</span> <span class="token string">"alarm_test"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"message is NULL\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

#if 0
 //这个看需求添加,一般来说,信号是一种单向广播,加上这一句变单向单播
//param2: bus_name
if(!dbus_message_set_destination(msg, “hello.world.service”))
{
printf(“memory error\n”);
}
#endif

<span class="token comment">//添加参数的一些接口</span>
<span class="token function">dbus_message_iter_init_append</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dbus_message_iter_append_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span> DBUS_TYPE_STRING<span class="token punctuation">,</span> <span class="token operator">&amp;</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//入队</span>
<span class="token function">dbus_connection_send</span><span class="token punctuation">(</span>connection<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//发送</span>
<span class="token function">dbus_connection_flush</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//释放内存</span>
<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">return</span><span class="token punctuation">;</span>

}

void send_method_call(DBusConnection connection)
{
DBusMessage msg;
DBusMessageIter arg;
DBusPendingCall *pending;
int a = 100;
int b = 99;
int sum;

msg <span class="token operator">=</span> <span class="token function">dbus_message_new_method_call</span><span class="token punctuation">(</span><span class="token string">"hello.world.service"</span><span class="token punctuation">,</span> <span class="token string">"/hello/world"</span><span class="token punctuation">,</span><span class="token string">"hello.world"</span><span class="token punctuation">,</span> <span class="token string">"add"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>msg <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no memory\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">dbus_message_iter_init_append</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_append_basic</span> <span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span> DBUS_TYPE_INT32<span class="token punctuation">,</span><span class="token operator">&amp;</span>a<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no memory!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token keyword">return</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_append_basic</span> <span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span> DBUS_TYPE_INT32<span class="token punctuation">,</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no memory!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token keyword">return</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>

<span class="token comment">//入队message,等待回复</span>
<span class="token comment">//param1: 连接描述符</span>
<span class="token comment">//param2: message</span>
<span class="token comment">//param3: 相当于一个回调的一个描述符,为了获了返回的消息</span>
<span class="token comment">//param4: 超时间. -1代表无限</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_connection_send_with_reply</span> <span class="token punctuation">(</span>connection<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>pending<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no memeory!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span><span class="token punctuation">(</span>pending <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Pending is NULL, may be disconnect...\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//send</span>
<span class="token function">dbus_connection_flush</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//阻塞,直到接收到一个响应.</span>
<span class="token function">dbus_pending_call_block</span> <span class="token punctuation">(</span>pending<span class="token punctuation">)</span><span class="token punctuation">;</span>
msg <span class="token operator">=</span> <span class="token function">dbus_pending_call_steal_reply</span> <span class="token punctuation">(</span>pending<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>msg <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"reply is null. error\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//释放pending内存 </span>
<span class="token function">dbus_pending_call_unref</span><span class="token punctuation">(</span>pending<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//解析参数</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_init</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>arg<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no argument, error\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_message_iter_get_arg_type</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">)</span> <span class="token operator">!=</span> DBUS_TYPE_INT32<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"paramter type error\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">dbus_message_iter_get_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">" a(%d) + b(%d) = %d\n"</span><span class="token punctuation">,</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> sum<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">return</span><span class="token punctuation">;</span>

}

int main(int argc, char argv)
{
DBusConnection *connection;

connection <span class="token operator">=</span> <span class="token function">init_bus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>connection <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"connect to bus failed...\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
    <span class="token comment">//发送一个信号及一个方法调用</span>
<span class="token function">send_signal</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">send_method_call</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165

(2) 服务端代码

service.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus.h>
#include <unistd.h>

DBusConnection init_bus()
{
DBusConnection connection;
DBusError err;
int ret = 0;

<span class="token function">dbus_error_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//与session dbus 建立连接</span>
<span class="token comment">//param1:bus type = {DBUS_BUS_SESSION, DBUS_BUS_SYSTEM} 一个系统dbus, 一个普通用户dbus</span>
<span class="token comment">//param2:错误信息,包括错误名与错误信息.</span>
connection <span class="token operator">=</span> <span class="token function">dbus_bus_get</span><span class="token punctuation">(</span>DBUS_BUS_SESSION<span class="token punctuation">,</span> <span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_error_is_set</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Connection Error: %s--%s\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>name<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">dbus_error_free</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//为连接设置一个bus name: bus_name;</span>
<span class="token comment">//param 1: 连接描述符</span>
<span class="token comment">//param 2: 请求bus要分配的bus name(逻辑上讲,bus name可以是任何字符串,只要符合命名规则)</span>
<span class="token comment">//param 3: flags ={DBUS_NAME_FLAG_REPLACE_EXISTING, </span>
<span class="token comment">//					DBUS_NAME_FLAG_ALLOW_REPLACEMENT,</span>
<span class="token comment">//					DBUS_NAME_FLAG_DO_NOT_QUEUE</span>
<span class="token comment">//					 }</span>
<span class="token comment">//param 4: err info</span>
ret <span class="token operator">=</span> <span class="token function">dbus_bus_request_name</span><span class="token punctuation">(</span>connection<span class="token punctuation">,</span> <span class="token string">"hello.world.service"</span><span class="token punctuation">,</span> DBUS_NAME_FLAG_REPLACE_EXISTING<span class="token punctuation">,</span> <span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_error_is_set</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Name Error: %s--%s\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>name<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">dbus_error_free</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span><span class="token punctuation">(</span>ret <span class="token operator">!=</span> DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER<span class="token punctuation">)</span>
	<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

<span class="token comment">//注册感兴趣的signal: 来自接口dbus.test.signal.sender</span>
<span class="token comment">//param1: 连接描述符</span>
<span class="token comment">//param2: match rule (常用的类型: sender=</span>
<span class="token comment">//									interface=</span>
<span class="token comment">//									type=</span>
<span class="token comment">//									member= )</span>
<span class="token comment">//param3: err info</span>
<span class="token comment">//只设置一个type = signal,表示所有信号都接受.也可以加上接口,发送者bus_name</span>
<span class="token function">dbus_bus_add_match</span><span class="token punctuation">(</span>connection<span class="token punctuation">,</span> <span class="token string">"type='signal'"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//阻塞,直到消息发送成功.</span>
<span class="token function">dbus_connection_flush</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_error_is_set</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"add Match Error %s--%s\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>name<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">dbus_error_free</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> connection<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> connection<span class="token punctuation">;</span>

}

void handle_message(DBusConnection connection)
{
DBusMessage msg;
DBusMessageIter arg;
char *str;

<span class="token keyword">while</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token comment">//param1: 连接描述符</span>
	<span class="token comment">//param2: 超时时间, -1无限超时时间</span>
	<span class="token function">dbus_connection_read_write</span><span class="token punctuation">(</span>connection<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">//从队列中取出一条消息</span>
	msg <span class="token operator">=</span> <span class="token function">dbus_connection_pop_message</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span> 
	<span class="token keyword">if</span><span class="token punctuation">(</span>msg <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
	<span class="token punctuation">{<!-- --></span>
		<span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token keyword">continue</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token comment">//这里应该过滤path,暂且不做</span>
	<span class="token comment">//打印出消息对象路径</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"path: %s\n"</span><span class="token punctuation">,</span> <span class="token function">dbus_message_get_path</span> <span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">//param1: message</span>
	<span class="token comment">//param2: interface 这个名字必须与发送那个接口一样.才能处理</span>
	<span class="token comment">//param3: singal name 方法名也必须一样.</span>
	<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_message_is_signal</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token string">"aa.bb.cc"</span><span class="token punctuation">,</span> <span class="token string">"alarm_test"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">{<!-- --></span>
		<span class="token comment">//解析message 参数,0为无参数.</span>
		<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_init</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>arg<span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token punctuation">{<!-- --></span>
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no argument\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		<span class="token comment">//获取第一个参数类型</span>
		<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_message_iter_get_arg_type</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">)</span> <span class="token operator">!=</span> DBUS_TYPE_INVALID<span class="token punctuation">)</span>
		<span class="token punctuation">{<!-- --></span>
			<span class="token comment">//获取参数的值</span>
			<span class="token function">dbus_message_iter_get_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span><span class="token operator">&amp;</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"recv param --: %s\n"</span><span class="token punctuation">,</span> str<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		
	<span class="token punctuation">}</span>
	<span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_message_is_method_call</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token string">"hello.world"</span><span class="token punctuation">,</span> <span class="token string">"add"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">{<!-- --></span><span class="token comment">//处理 add 远程调用.</span>
		DBusMessage <span class="token operator">*</span>rp<span class="token punctuation">;</span>
		DBusMessageIter r_arg<span class="token punctuation">;</span>
		<span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
		<span class="token keyword">int</span> b <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
		<span class="token keyword">int</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"service: add  function\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

		<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_init</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>arg<span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token punctuation">{<!-- --></span>
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no argument!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">goto</span> out<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">dbus_message_iter_get_arg_type</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">)</span> <span class="token operator">!=</span> DBUS_TYPE_INT32<span class="token punctuation">)</span>
		<span class="token punctuation">{<!-- --></span>
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"argument error\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">goto</span> out<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		<span class="token function">dbus_message_iter_get_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span>

		<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_message_iter_next</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token punctuation">{<!-- --></span>
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"too few argument!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">goto</span> out<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		<span class="token comment">//check argument type....</span>
		<span class="token function">dbus_message_iter_get_basic</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>arg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
		sum <span class="token operator">=</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span>

out:
//new 一个回应对象
rp = dbus_message_new_method_return(msg);
dbus_message_iter_init_append(rp, &r_arg);
if(!dbus_message_iter_append_basic(&r_arg, DBUS_TYPE_INT32, &sum))
{
printf(“no memory!!\n”);
return;
}

		<span class="token comment">//param3: 这个跟消息序列有关</span>
		<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">dbus_connection_send</span><span class="token punctuation">(</span>connection<span class="token punctuation">,</span> rp<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token punctuation">{<!-- --></span>
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"no memory!!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">return</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		<span class="token function">dbus_connection_flush</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>rp<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token comment">//释放空间</span>
	<span class="token function">dbus_message_unref</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//dbus_bus_remove_match();</span>

}

int main(int argc, char argv)
{
int ret = 0;
DBusConnection *connection;

connection <span class="token operator">=</span> <span class="token function">init_bus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>connection <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"connect the dbus failed...\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">handle_message</span><span class="token punctuation">(</span>connection<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174

(3)执行结果

客户端

在这里插入图片描述

服务端

在这里插入图片描述

参考博客:
D-Bus 学习
DBUS基础知识(非常全面)
DBus 入门与应用 -- DBus 的 C 编程接口
dbus 简单编程(二)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DBUS入门与C编程 的相关文章

  • Ubuntu20.4安装ROS系统教程(自用)

    1 Ubuntu各个版本系统对应的ROS版本 1 2Ubuntu16 04与ROS kinetic的安装 1 2 1Ubuntu16 04配置 1 2 2安装ROS kinetic版 1 3Ubuntu18 04和ROS melodic的安
  • UART 空闲中断+DMA接收流程

    在项目中利用UART空闲中断接收外部信号 xff0c 利用DMA接收 xff0c 实现外部到内存的传输 通过分析其它文章的代码 xff0c 大概如下 xff1a span class token comment 配置 DMA Stream
  • 5分钟带你从数据类型了解Java相比C/C++有什么优势

    数据类型是一门语言的血肉 xff0c 通过这5分钟的浏览 xff0c 只学过C C 43 43 的小伙伴会初步了解Java的一些特性 xff0c 学过一点Java的朋友在读完这篇文章后也一定会对Java的语法规范有更深刻的了解 Java数据
  • 备赛电赛学习硬件篇(一):电机部分

    目录 一 电机选型 二 电机的正反转 xff0c 刹车 一 电机选型 1 电机类型 无刷电机较贵 xff0c 但是静音且损耗小 xff0c 由于霍尔元件的特殊性 xff08 不带霍尔需要转速高的时候才可以利用反电动势准确确定转子的位置 xf
  • 【总线】一文看懂RS232和RS485通信总线

    目录 RS232概述 RS232特性 RS485 概述 RS485 特性 RS232 和 RS485 的区别 区别总结 RS232概述 RS 232接口符合电子工业联盟 xff08 EIA xff09 建立的串行数据通信接口标准 原始编号是
  • 【C++学习笔记】vector构造函数

    文章目录 1 vector构造函数说明 xff1a 2 实战 xff1a 2 1 vector构造函数代码示例2 2 输出 3 参考资料 1 vector构造函数说明 xff1a span class token keyword templ
  • 请求报文/相应报文

    一 请求报文分为4个部分 请求行 请求头 请求空行 请求体 1 1 请求行 主要是3个部分 GET 请求方式 1 2 请求地址 所带的参数 demo demo php userName 61 E6 9D 8E E5 9B 9B amp us
  • python+requests——高级用法——auth认证

  • C语言char指针的使用

    在c语言中 xff0c char指针不仅能指向char变量 xff0c 还能指向常量字符串 xff0c 同时也能指向一个char数组的 想要访问单个字符 xff0c 就要通过 来进行解引用 xff0c 若是要访问整个数组或字符串的话 xff
  • HTTP协议的请求格式解析

    HTTP协议是一个使用较多的应用层协议 xff0c 它是一个请求 响应式的一个协议 xff0c 就是我客户端给你发一个请求 xff0c 你客户端需要返回给我一样响应 首先我们来看一下HTTP协议的请求格式 HTTP请求格式 xff1a HT
  • 运行Gazebo+moveit+Rviz,报错,提示无控制器

    在rviz里规划成功后 xff0c 执行显示failed rviz里能规划 xff0c 但是Gazebo里动不了 moveit报错如下 xff1a WARN 1679466487 132361192 26 763000000 Waiting
  • 基于UDP协议搭建的简单客户端与服务器(UDP协议)

    UDP协议 UDP协议的介绍1 UDP的缺点 基于UDP实现的回显服务器基于UDP实现的客户端 UDP协议的介绍 UDP协议特点 xff1a 1 无连接 2 面向数据报 3 不可靠传输 4 全双工 16位源端口号 目的端口号 xff1a 表
  • C++之AStar寻路算法

    仅以记录 有一种算法 名为AStar 它的作用是求图中两点之间的最短路径 沉迷 该算法的我 自己编写了一个版本 注释虽少 但求传神 代码虽 恶心 但求理解 include lt iostream gt include lt vector g
  • 使用livox_viewer2对激光雷达livox_mid360进行调试

    准备 系统 windows10 硬件 xff1a livox mid360 软件 xff1a livox viewer2 测试 连接号激光雷达设备 xff0c 电脑ip相关设置和livox avia一样 livox系列激光雷达ip设置都是一
  • 听说你还不会制作“GIF动图”,手把手包教会,这不就来了吗

    近期 xff0c 看了好多写的博客 xff0c xff08 不管是前端HTML的还是后端Java的 xff0c 前端制作的3D部分的效果图需要展示动图 xff09 发现有点还存在想使用动图 xff0c 但是不会制作 xff0c 又或者是制作
  • HTML+js实现贪吃蛇小游戏(内含完整代码)

    案例分析 看图拆解游戏 首先我们根据图片上的内容把这个游戏拆解成几个部分去单独看 xff1a 最外面的大盒子包裹着内容加边框限制蛇的活动范围 xff0c 整个范围可以看成由许多小方格排列构成的 xff0c 例如这样子的 xff1a xff1
  • 【华为Hilink SDK Linux系统开发】第三章:华为hilink SDK Linux系统网关适配

    mark xff1a https blog csdn net qq 24550925 article details 107282773 关注嘉友创科技公众号 声明 xff1a 文章只做技术交流 xff0c 没有其他任何用途 xff0c 侵
  • 快速去除GIF动图的背景(让背景变透明),保姆级教程

    很多小伙伴在看到好看的动图效果时 xff0c 想用在自己的页面上 xff0c 可是常常会碰到一些动图背景颜色不符合自己的需求 xff0c 所以会产生修改动图背景的想法 xff0c 但是GIF动图终究是GIF动图 xff0c 不像静态图片那样
  • Vue在HTML中如何使用

    x1f440 Vue是什么 一套用于构建用户界面的渐进式JavaScript框架 构建用户界面 xff1a 数据变成界面渐进式 xff1a Vue可以自底向上逐层的应用 x1f440 Vue如何使用 一 引入vue js lt script
  • 简单记录一下怎么看package.json文件

    首先每个vue工程文件从仓库克隆代码下来的时候 xff0c 一般都会包含这个文件 xff0c 这个文件非常重要 xff0c package json包含了关于项目重要信息 xff0c 如下图所示 其中包含了name version desc

随机推荐

  • 项目中常用到的前端vue根据后端接口返回文件地址实现在线预览和下载功能

    简简单单的记录一下项目中做过的东西 项目中时常会有要求查看附件 xff0c 附件的下载的要求 xff0c 在这里简单记录一下前端vue根据后端接口返回文件地址实现在线预览和下载功能 x1f440 文件在线预览 目前我这里使用的是点击a链接跳
  • 记录面试问题

    以下问题不分先后 xff0c 按照印象深浅排序 xff0c 可能一次记录不完成 xff0c 后面想起来会及时补充 xff0c 如有不对 xff0c 恳请各位围观大佬多多指教 x1f64f 印象最深的是一道很简单很简单的题目 xff0c 我结
  • C++中“.“,“->“,“:“和“::“的区别

    在 C 43 43 中 xff0c 34 34 xff0c 34 gt 34 xff0c 34 34 和 34 34 都是运算符 xff0c 它们的作用是明显不同的 xff0c 但是初学者很容易被其迷惑 1 34 34 是成员访问运算符 x
  • ubuntu系统中忘记root密码的解决办法

    1 启动ubuntu按shift进入grub菜单 xff1b 2 选择recovery mode进入Recovery Menu界面 xff0c 选择root Drop to root shell prompt 3 修改root密码操作 xf
  • C++语言实现哈希表中的线性探测法和平方探测法

    哈希表 xff08 Hash表 xff09 xff0c 也称为散列表 xff0c 是一种数据结构 xff0c 通过使用哈希函数将键映射到数组的特定位置来实现高效的查找 插入和删除操作 哈希函数将键转换为一个整数 xff0c 这个整数对应数组
  • C++实现的二叉树前序遍历函数

    include lt iostream gt using namespace std struct TreeNode int val TreeNode left TreeNode right TreeNode int x val x lef
  • c语言和c++实现层序遍历

    层序遍历是一种二叉树的遍历方式 xff0c 也称为广度优先遍历 xff0c 它的遍历顺序是 xff1a 从上到下 xff0c 从左到右 xff0c 一层一层地遍历整棵树 在 C 语言中 xff0c 我们可以使用队列来实现层序遍历 具体实现步
  • C语言获取wifi状态

    mark https blog csdn net dongyoubin article details 122134198 int getWirelessStatus char ath char ssid char ipAddr
  • 最全Visual Studio版本号对应表VisualStudioVersion

    名字 版本号 简称 全称 msvc70 VC7 0 VS2002 Microsoft Visual Studio 2002 msvc71 VC7 1 VS2003 Microsoft Visual Studio 2003 msvc80 VC
  • 二叉树静态实现的示例代码

    使用指针对于初学者容易出现很多困惑 下面是一个完整的二叉树静态实现的示例代码 xff0c 包括初始化 插入节点 各种遍历方法以及一些辅助函数 include lt stdio h gt include lt stdlib h gt defi
  • 广度优先搜索(BFS)算法实现二叉树层序遍历的 C++ 代码

    include lt iostream gt 输入输出流 include lt vector gt 向量容器 include lt queue gt 队列容器 using namespace std 命名空间 定义二叉树节点结构体 stru
  • PAT 1005 Spell It Right

    Given a non negative integer N your task is to compute the sum of all the digits of N and output every digit of the sum
  • 在PC的Ubuntu虚拟机上完成一个TCP 服务器,在设备上实现一个TCP客户端

    要求 在虚拟机上实现一个服务器 xff0c 设备终端上实现一个客户端设备客户端每隔 1 秒 检测一次网卡eth2 1 xff08 WAN口网卡 xff09 的信息 xff08 使用popen调用ifconfig xff09 然后将RX和TX
  • TCP发送数据、接受数据及TCP通信程序练习

    目录 一 TCP发送数据 二 TCP接收数据 三 TCP通信程序练习 一 TCP发送数据 Java中的TCP通信 xff1a Java对于基于TCP协议的网络提供了良好的封装 xff0c 使用Socket对象来代表两端的通信端口 xff0c
  • slam学习笔记

    ubuntu20 04 使用vs code编写 现放cmake文件 xff08 记得链接库文件和配置C 43 43 版本 xff09 cmake minimum required VERSION 2 8 project learingMat
  • SLAM学习笔记

    编译环境ubuntu20 04 vs code xff08 李群 李代数 xff09 先是CMakeLists txt cmake minimum required VERSION 3 0 project learning sophus s
  • SLAM学习笔记

    编译环境ubuntu20 04 xff0c vs code 先cmake文件 cmake minimum required VERSION 2 8 project image set CMAKE BUILD TYPE 34 Release
  • SLAM学习笔记

    编译环境ubuntu20 04 vscode ceres库2 0 0 g2o库同gaoxiang12 slambook2中的版本号一致 cmake文件 cmake minimum required VERSION 2 8 project c
  • 数据结构之C语言单链表操作

    实验目的 xff1a 1 xff0e 创建一个带头结点的单链表 2 xff0e 插入元素操作 xff1a 将新元素x插入到单链表head的头部 将新元素x插入到单链表head的尾部 将新元素x插入到单链表head中第i个元素之后 3 xff
  • DBUS入门与C编程

    https blog csdn net weixin 45566765 article details 125028296 一 D Bus简介 1 D Bus是什么 D Bus最主要的用途是在 Linux 桌面环境为进程提供通信 xff0c