Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1028839
  • 博文数量: 166
  • 博客积分: 10217
  • 博客等级: 上将
  • 技术积分: 2133
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-09 19:45
文章分类

全部博文(166)

文章存档

2012年(3)

2011年(7)

2010年(18)

2009年(59)

2008年(79)

我的朋友

分类: LINUX

2008-06-26 21:17:39

以下为转载,只转载了一部分,详见:http://blog.csdn.net/cuijpus/archive/2008/01/30/2073993.aspx
使用Glib封装过的D-Bus
这部分的内容:
  • GObject介绍
  • 使用XML文件定义D-Bus接口
  • 自动生成proxy/stub代码
  • 创建一个简单的D-Bus对象
  • 通过D-Bus发布一个GType类型
  • 客户端如何使用Glib封装过的D-Bus
  • D-Bus的自省功能
 
GObject介绍
为了在运行时把GTK+ widgets绑定到解释语言,一些牛人就用C语言实现了相对难以理解的面向对象的机制。根据你个人的爱好,你可以把这种面向对象称之为GObject或者GTypeGTypeGObject的底层基础。GObject/GTypeGlib的一部分,并且单独编译成一个库:libgobject,对于GObject的详细介绍,大家可以到网上google一下,另外还要仔细阅读其代码,非常巧妙的实现!
这里的例子:实现一个非继承的类,类的接口去访问和修改两个私有的成员变量:value1vaule2, value132位的整数,value2是一个gdouble类型的数据。
我们需要实现类构造函数和对象构造函数。这里,这两个构造函数都比较简短。如果你了解C++,你会发现这里怎么有两个构造函数呢?C++只有一个啊!不错,这就是GObject别扭的地方。慢慢你就会习惯的,当你很喜欢它后,你可能觉得C++是个另类。因为你了解C++的构造函数比较早,这个晚了些时候。
 
使用XML文件定义D-Bus接口:
 
由于我们主要的目的是做一个可以在D-Bus中使用的对象,因此我们从一个最简单的地方入手,通过dbus-binding-tool工具,这个工具会自动由XML文件生成clientserver端的代码。我们就是把需要的接口安装XML语法定义在一个XML文件中就行了。
定义方法,即函数:用method来包含,其name是指定这个函数的名字,这个指定的名字会拷贝到生成的stub代码里面;函数method带一个参数:new_value, 包含。其中对于参数类型(type)的的形式,需要参考D-Bus的参数类型定义。
   
    name="setvalue1">
      type="i" name="new_value" direction="in"/>
   
 
// direction表示入口参数还是出口参数,in:入口; out: 出口参数,如果不指定in或者out, 默认为in;
// type 的指定要参考D-Bus的类型定义,见下表;
 
其中,最难搞的就是要严格指定参数(arg)的类型(type),正是这个type来定义参数的数据类型,D-Bus定义的参数类型如下:

Conventional Name
Code
Description
INVALID
0 (ASCII NUL)
Not a valid type code, used to terminate signatures
BYTE
121 (ASCII 'y')
8-bit unsigned integer
BOOLEAN
98 (ASCII 'b')
Boolean value, 0 is FALSE and 1 is TRUE. Everything else is invalid.
INT16
110 (ASCII 'n')
16-bit signed integer
UINT16
113 (ASCII 'q')
16-bit unsigned integer
INT32
105 (ASCII 'i')
32-bit signed integer
UINT32
117 (ASCII 'u')
32-bit unsigned integer
INT64
120 (ASCII 'x')
64-bit signed integer
UINT64
116 (ASCII 't')
64-bit unsigned integer
DOUBLE
100 (ASCII 'd')
IEEE 754 double
STRING
115 (ASCII 's')
UTF-8 string (must be valid UTF-8). Must be nul terminated and contain no other nul bytes.
OBJECT_PATH
111 (ASCII 'o')
Name of an object instance
SIGNATURE
103 (ASCII 'g')
A type signature
ARRAY
97 (ASCII 'a')
Array
STRUCT
114 (ASCII 'r'), 40 (ASCII '('), 41 (ASCII ')')
Struct
VARIANT
118 (ASCII 'v')
Variant type (the type of the value is part of the value itself)
DICT_ENTRY
101 (ASCII 'e'), 123 (ASCII '{'), 125 (ASCII '}')
Entry in a dict or map (array of key-value pairs)
 
我用蓝色标出的是比较常用的,你要根据你参数的需要,把上述第二列的类型码写到XML文件中去。开始你可能不习惯,慢慢就好了。
另外,D-Bus本身并不限制返回参数的个数,但是C语言只支持一个返回参数,因此如果你需要把其它需要携带回来的参数当作出口参数处理。其它的一些高级语言并不像C语言这样有限制。
 
下面是D-Bus函数所能支持的参数类型:(括号中是Glib对应的类型):
  • b: boolean (gboolean)
  • y: 8-bit unsigned integer (guint8)
  • q/n: 16-bit unsigned/signed integer (guint16/gint16)
  • u/i: 32-bit unsigned/signed integer (guint32/gint32)
  • t/x: 64-bit unsigned/signed integer (guint64/gint64)
  • d: IEEE 754 double precision floating point number (gdouble)
  • s: UTF-8 encoded text string with NUL termination (only one NUL allowed) (gchar* with additional restrictions)
  • a: Array of the following type specification (case-dependent)
  • o/g/r/(/)/v/e/{/}: Complex types, please see the official D-Bus documentation on type signatures.
从这个列表可以看出,我们上面定义的函数:setvalue1有一个32位整形参数(new_value).这里定义的参数名称:new_value将会影响到所生成的stub代码,对于生成文档和D-Bus自省是非常有用的。
下面我们再定义另外一个函数:getvalue1, 这个函数用于返回当前对象的整数成员的值,没有入口参数,只有出口参数: cur_value。具体定义见下:
   
    name="getvalue1">
      type="i" name="cur_value" direction="out"/>
   
我们已经知道,D-Busmethod是隶属于interface的,就说一个interface可以有Nmethod, XML中,我们把这些method元素包含在interface元素中,借以表达这种隶属关系。这个interface的名字属性是可选的,你可以指定,也可以不指定,我们强烈推荐你写上这个名字,一是防止各个模块的interface重名,另外一个重要的功用是为了introspection.
再进一步,method隶属于interface, 那么interface又属于谁呢?隶属于object, 一个object可以有Ninterface. 我们把interface元素包含在node元素内。在XML中,node是最顶层的元素了。我们这个例子里面,只实现了一个interface(binding tool会自动增加introspection接口的,因此不必在XML文件中指定),到此,我们就写完了一个最基本的XML文件,如下:
version="1.0" encoding="UTF-8" ?>
  name="org.maemo.Value">
   
    name="getvalue1">
      type="i" name="cur_value" direction="out"/>
   
   
    name="setvalue1">
      type="i" name="new_value" direction="in"/>
   
 
 
再对上面的最基本的XML接口定义文件做些扩充:增加DTD扫描,其实这个可以不用。另外还有就是增加了2个函数定义:get_value2, set_value2
如果你需要写XML文件,强烈建议你在一个模板基础上写,就是拿个没有基本语法错误的模板,然后增加修改你的接口,这样容易成功,不要白手起家,不要在这个XML文件上面做过多的纠缠。
version="1.0" encoding="UTF-8" ?>
 
 
 "-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
 "">
 
 
  name="org.maemo.Value">
 
   
 
   
    name="getvalue1">
     
      type="i" name="cur_value" direction="out"/>
   
 
   
    name="getvalue2">
      type="d" name="cur_value" direction="out"/>
   
 
   
    name="setvalue1">
      type="i" name="new_value" direction="in"/>
   
 
   
    name="setvalue2">
      type="d" name="new_value" direction="in"/>
   
 
 
 
写完XML文件后,下面我们是不是可以使用D-Bus工具来生成代码了?别急!我们还要对XML文件做些自动检查。主要检查两个方面:是否符合XML1.0规范;验证XML结构(即:元素是否成对匹配)。结构验证的规则是由DTD(Document Type Definition)文档规定的。D-Bus规定的XML格式如下:

 
 
 
 
 
 
 
 
 
 
 

阅读(1812) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~