当前位置:   article > 正文

基于GDBus框架的进程间通信详解

gdbus

1. GDBus简介

首先简单介绍一下什么是GDBus。GDBus是一种基于d-bus技术的进程间通信框架,其中最核心的部分就是“Bus”,个人理解,它就是一个进程间通信的“桥梁”,不同的进程之间进行接收或者传递消息,都需要通过这个"Bus"总线。进程间通信的消息都会先发送到"Bus"总线上,然后再分发到目标进程上,"Bus"总线会根据收到消息的类型不同,采取不同的处理,主要处理可以分为两类:函数调用、信号广播。为了方便起见,我们假设有两个进程需要进行通信,一个Client进程,一个Server进程。

  1. 函数调用
    Client进程需要调用Server进程的某个方法(Method Call),请求信息会先发送给"Bus"总线,经过"Bus"总线处理后,再将请求信息发送到Server进程,调用相应的Method方法去执行某些操作,然后将操作结果返回给Client进程。
  2. 信号广播
    Server进程可以主动发送一些信号(Signal),Client进程可以选择注册感兴趣的信号。当Server发送信号时,消息同样会先发送到"Bus"总线上,如果Client进程正好注册接受该类型的信号,信号就会发送到Client进程上。

2. 生成D-Bus interface

实现Client和Server 进程通信的第一步,就是要定义好通信的接口。GDBus通信接口是在xml文件下描述的,然后通过gdbus-codegen工具就可以自动生成对应D-Bus interface源文件和头文件了。

Interface.xml:

<?xml version="1.0" encoding="UTF-8"?>
<node>
  <interface name="com.gdbus.demo">
    <method name="SetData">
      <arg name="data" type="s" direction="in"/>
      <arg name="response" type="s" direction="out"/>
    </method>
    <signal name="SendSignal">
      <arg name="sig" type="i"/>
    </signal>
  </interface>
</node>

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

这里我们将interface name定义为"com.gdbus.demo",然后分别定义了一个method方法和一个signal方法。
arg name表示参数名字,type表示参数类型,direction in和out分别表示入参和出参。
这里xml中定义的参数类型都是GVariant类型的,对于每个字符代表的含义,可以参照下表。
| GVariant数据类型 | 代表含义|
|–|–|–|
|b:G_VARIANT_TYPE_BOOLEAN的类型字符串| 布尔值。|
|y:G_VARIANT_TYPE_BYTE的类型字符串 |一个字节。
|n:G_VARIANT_TYPE_INT16的类型字符串; |有符号的16位整数。
|q:G_VARIANT_TYPE_UINT16的类型字符串| 一个无符号的16位整数。
|i:G_VARIANT_TYPE_INT32的类型字符串 |有符号的32位整数。
|u:G_VARIANT_TYPE_UINT32的类型字符串| 一个无符号的32位整数。
|x:G_VARIANT_TYPE_INT64的类型字符串 |有符号的64位整数。
|t:G_VARIANT_TYPE_UINT64的类型字符串| 一个无符号的64位整数。
|h:G_VARIANT_TYPE_HANDLE的类型字符串| 一个有符号的32位值,按照惯例,该值用作与D-Bus消息一起发送的文件描述符数组的索引。
|d:G_VARIANT_TYPE_DOUBLE的类型字符串| 双精度浮点值。
|s:G_VARIANT_NEW_STRING的类型字符串 |一个字符串。
|o:G_VARIANT_TYPE_OBJECT_PATH的类型字符串| D-Bus对象路径形式的字符串。
|g:G_VARIANT_TYPE_SIGNATURE的类型字符串 |D-Bus类型签名形式的字符串。
|?:G_VARIANT_TYPE_BASIC的类型字符串 |一个不确定类型,它是任何基本类型的超类型。
|v:G_VARIANT_TYPE_VARIANT的类型字符串| 包含任何其他类型的值的容器类型。
|a:用作另一个类型字符串的前缀,表示该类型的数组| 例如,类型字符串“ ai”是带符号的32位整数数组的类型。
|m:用作另一个类型字符串的前缀,表示该类型的“也许”或“可空”版本| 例如,类型字符串“ ms”是可能包含字符串或不包含任何值的值的类型。
|():用于封装零个或多个其他串联类型的字符串以创建元组类型| 例如,类型字符串“(is)”,是整数和字符串对的类型。
|r:G_VARIANT_TYPE_TUPLE的类型字符串 |一个不定类型,它是任何元组类型的超类型,而与元素数无关。
定义完这个xml文件,我们只需要在终端输入以下命令,就可以生成其对应的源文件了:

gdbus-codegen --generate-c-code=gdbusdemo_gen Interface.xml

3.GDBus interface源文件详解

自己在学习GDBus的时候,看过很多篇文章,对gdbus-codegen生成的D-Bus interface源文件,很多文章都是一带而过,由于后面编写Server和Client部分的代码都需要用到这些接口,如果不理解的话,代码写起来也是一头雾水,只能去网上复制别人的代码,到最后也不知道实现过程和原理。。 为了加深对GDBus的理解,笔者自己去研究了一下,下面带大家看一看生成的这些文件中到底有什么神秘的东西。

3.1
首先,你会看到源文件中定义了如下结构体(Introspection data):
在这里插入图片描述
让我们来看一下这些结构体的具体组成:

_ExtendedGDBusArgInfo:

static const _ExtendedGDBusArgInfo _com_gdbus_dem
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/122724
    推荐阅读
    相关标签
      

    闽ICP备14008679号