dbus实例讲解(四上):使用dbus

dbus-glib是dbus底层接口的一个封装。本讲我们用dbus-glib做一个dus接口,,并写一个客户程序。

1、接口1.1、编写接口描述文件

首先编写接口描述文件。我们要实现的连接的公共名是”org.freesmartphone.ogsmd”,接口描述文件如下:

$ cat smss.xml<?xml version=”1.0″ encoding=”UTF-8″ ?><node> <interface><method><arg type=”s”/><arg type=”s”/><arg type=”a{sv}”/><arg type=”i” direction=”out”/></method><signal><arg type=”s”/><arg type=”s”/><arg type=”a{sv}”/></signal> </interface></node>

我们要在连接”org.freesmartphone.ogsmd”中实现对象”/org/freesmartphone/GSM/Device”。这个对象有接口”org.freesmartphone.GSM.SMS”。这个接口有一个SendMessage方法和一个IncomingMessage信号。

SendMessage方法和IncomingMessage信号除了两个字符串参数外,还有一个a{sv}参数,这是一个哈希表,即python的字典。键-值对的键类型是字符串,值类型是VARIANT。这个接口是openmoko fso接口的一部分。但为简单起见,本例在哈希表部分,只用三个键值。

请注意方法和信号名应采用单词连写,首字母大写的格式。

1.2、由接口描述文件生成绑定文件

有一个叫dbus-binding-tool的工具,它读入接口描述文件,产生一个绑定文件。这个文件包含了dbus对象的接口信息。在主程序中我们通过dbus_g_object_type_install_info函数向dbus-glib登记对象信息(DBusGObjectInfo结构)。

本例使用了autotool,在Makefile.am中可以这样调用dbus-binding-tool:

smss-glue.h: smss.xml$(LIBTOOL) –mode=execute dbus-binding-tool –prefix=gsm_sms –mode=glib-server –output=smss-glue.h $(srcdir)/smss.xml

“–prefix”参数定义了对象前缀。设对象前缀是$(prefix),则生成的DBusGObjectInfo结构变量名就是dbus_glib_$(prefix)_object_info。绑定文件会为接口方法定义回调函数。回调函数的名称是这样的:首先将xml中的方法名称转换到全部小写,下划线分隔的格式,然后增加前缀”$(prefix)_”。例如:如果xml中有方法SendMessage,绑定文件就会引用一个名称为$(prefix)_send_message的函数。

绑定文件还会为接口方法生成用于散集(Unmarshaling)的函数。在dbus消息中,方法参数是以流格式存在的。该函数将方法参数由数据流还原到glib的数据格式,并传入方法的回调函数。本例中,dbus-binding-tool生成以下的smss-glue.h:

$ cat smss-glue.h/* Generated by dbus-binding-tool; do not edit! */#ifndef __dbus_glib_marshal_gsm_sms_MARSHAL_H__#define __dbus_glib_marshal_gsm_sms_MARSHAL_H__#include<glib-object.h>G_BEGIN_DECLS#ifdef G_ENABLE_DEBUG#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)#define g_marshal_value_peek_char(v)g_value_get_char (v)#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)#define g_marshal_value_peek_int(v)g_value_get_int (v)#define g_marshal_value_peek_uint(v)g_value_get_uint (v)#define g_marshal_value_peek_long(v)g_value_get_long (v)#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)#define g_marshal_value_peek_enum(v)g_value_get_enum (v)#define g_marshal_value_peek_flags(v) g_value_get_flags (v)#define g_marshal_value_peek_float(v) g_value_get_float (v)#define g_marshal_value_peek_double(v) g_value_get_double (v)#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)#define g_marshal_value_peek_param(v) g_value_get_param (v)#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)#define g_marshal_value_peek_object(v) g_value_get_object (v)#else /* !G_ENABLE_DEBUG *//* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. *Do not access GValues directly in your code. Instead, use the *g_value_get_*() functions */#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int#define g_marshal_value_peek_char(v)(v)->data[0].v_int#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint#define g_marshal_value_peek_int(v)(v)->data[0].v_int#define g_marshal_value_peek_uint(v)(v)->data[0].v_uint#define g_marshal_value_peek_long(v)(v)->data[0].v_long#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64#define g_marshal_value_peek_enum(v)(v)->data[0].v_long#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong#define g_marshal_value_peek_float(v) (v)->data[0].v_float#define g_marshal_value_peek_double(v) (v)->data[0].v_double#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer#endif /* !G_ENABLE_DEBUG *//* BOOLEAN:STRING,STRING,BOXED,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.3YAGNU:1) */extern void dbus_glib_marshal_gsm_sms_BOOLEAN__STRING_STRING_BOXED_POINTER_POINTER (GClosure*closure,GValue*return_value,guintn_param_values,const GValue *param_values,gpointerinvocation_hint,gpointermarshal_data);voiddbus_glib_marshal_gsm_sms_BOOLEAN__STRING_STRING_BOXED_POINTER_POINTER (GClosure*closure,GValue*return_value,guintn_param_values,const GValue *param_values,gpointerinvocation_hint,gpointermarshal_data){ typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_STRING_BOXED_POINTER_POINTER) (gpointerdata1,gpointerarg_1,gpointerarg_2,gpointerarg_3,gpointerarg_4,gpointerarg_5,gpointerdata2); register GMarshalFunc_BOOLEAN__STRING_STRING_BOXED_POINTER_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return;g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 6);if (G_CCLOSURE_SWAP_DATA (closure)){data1 = closure->data;data2 = g_value_peek_pointer (param_values + 0);} else{data1 = g_value_peek_pointer (param_values + 0);data2 = closure->data;} callback = (GMarshalFunc_BOOLEAN__STRING_STRING_BOXED_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);v_return = callback (data1,g_marshal_value_peek_string (param_values + 1),g_marshal_value_peek_string (param_values + 2),g_marshal_value_peek_boxed (param_values + 3),g_marshal_value_peek_pointer (param_values + 4),g_marshal_value_peek_pointer (param_values + 5),data2);g_value_set_boolean (return_value, v_return);}G_END_DECLS#endif /* __dbus_glib_marshal_gsm_sms_MARSHAL_H__ */#include static const DBusGMethodInfo dbus_glib_gsm_sms_methods[] = { { (GCallback) gsm_sms_send_message, dbus_glib_marshal_gsm_sms_BOOLEAN__STRING_STRING_BOXED_POINTER_POINTER, 0 },};const DBusGObjectInfo dbus_glib_gsm_sms_object_info = { 0, dbus_glib_gsm_sms_methods, 1,”org.freesmartphone.GSM.SMS/0SendMessage/0S/0number/0I/0s/0contents/0I/0s/0featuremap/0I/0a{sv}/0arg3/0O/0F/0N/0i/0/0/0″,”org.freesmartphone.GSM.SMS/0IncomingMessage/0/0″,”/0″};

在包含绑定文件前,我们必须声明绑定文件要引用的回调函数。

2 对象2.1 对象定义有多远,走多远,把足迹连成生命线。

dbus实例讲解(四上):使用dbus

相关文章:

你感兴趣的文章:

标签云: