本文共 4928 字,大约阅读时间需要 16 分钟。
在嵌入式系统中利用dbus重要有两个方面的用处:
1:历程间通信 2:告终client/server形式;2也是1的翔实出现形式;
包括dbus自带的例子,都是批准dbus对数据的封装,告终client/server形式的,
缺点有二: 1 一个API要定义一个xml接口描写 2 数据封装极其混杂,极其不利于尔后接口的伸展;为了客服上面的缺点,长进可伸展性和效率,能够这么做:
万一一个利用分为client,server两端的话,要高效率的告终client/server之间 的通信,能够批准如下措施:第一步:定义一个通用的API xml 接口描写,暂号召为dbus_general.xml
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/org/freedesktop/DBus/General_api"> <inte***ce name="org.freedesktop.DBus.general_api"> <method name="client_request"> <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="__client_request_cb"/> <arg type="i" name="action_id" direction="in" />//这个地方即便不同API的ID <arg type="i" name="input_int" direction="in" />//这个参数能够用www.zhuangyuan.org,也能够无须 <arg type="ay" name="input_garray" direction="in" />//这个Garray用来从client递交数据,包括混杂的数据构造到server <arg type="i" name="outut_int" direction="out" />//这个能够用,也能够无须 <arg type="ay" name="output_garray" direction="out" />//这个Garray用来从server侧传回数据到client侧 <arg type="i" name="result" direction="out" /> </method> </inte***ce> </node>大家懂得:在dbus文档中有这么的描写,
ay | Array of bytes | DBUS_TYPE_G_BYTE_ARRAY | GArray * |g_array_free
大家都不常用字节数组(GArray),大家常用的是integar,string等;
这个通用的模板关键之处即便这个Garray, Garray本身是个容器,这个 容器里面能够装任何东西。我们即方便用这个GArray来告终client与server之间数据的递交,无论想递交
什么要的数据;第二步:用dbus的工具函数生成stub/proxy头文件,这一步写到Makefile脚本中,尔后无须修正了;
dbus-binding-tool --mode=glib-server --prefix=your_module_name dbus_general.xml > general_stub.h
dbus-binding-tool --mode=glib-client --prefix=your_module_name dbus_general.xml > general_proxy.h生成的头文件,大家等闲不要动它们,直接利用就能够了;
general_proxy.h:
.....
client_request (DBusGProxy *proxy, const gint IN_action_id, const gint IN_input_int, const GArray* IN_input_garray, gint* OUT_output_int, GArray** OUT_output_garray, gint* OUT_result, GError **error){
return dbus_g_proxy_call (proxy, "request", error, G_TYPE_INT, IN_action_id, G_TYPE_INT, IN_input_int, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), IN_input_garray, G_TYPE_INVALID, G_TYPE_INT, OUT_output_int, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), OUT_output_garray, G_TYPE_INT, OUT_result, G_TYPE_INVALID); } .....general_stub.h:
.....#include <dbus/dbus-glib.h>
static const DBusGMethodInfo dbus_glib_your_module_name_methods[] = { { (GCallback) __client_request_cb, dbus_glib_marshal_your_module_name_BOOLEAN__INT_INT_BOXED_POINTER_POINTER_POINTER_POINTER, 0 }, };const DBusGObjectInfo dbus_glib_your_module_name_object_info = {
0, dbus_glib_your_module_name_methods, 1, "org.freedesktop.DBus.general_api/0client_request/0S/0action_id/0I/0i/0input_int/0I/0i/0input_garray/0I/0ay/0output_int/0O/0F/0N/0i/0output_garray/0O/0F/0N/0ay/0result/0O/0F/0N/0i/0/0/0", "/0", "/0" }; ......第三步:告终client侧,重要是直接调用general_proxy.h的接口函数client_request(),用GArray传入你的数组(能够携带任何你自己定义的数据构造)
gboolean proxy_func1 (void)
{ intapi_id = 0; //这个在不同的proxy_func里面能够有不同的值,重要是判别函数作用 GArray*in_array = NULL; GArray*out_array = NULL;//在这里无须分配内存,放在server侧做内存分配 in_array = g_array_new(FALSE, FALSE, sizeof(guint8)); if (!in_array) return FALSE; //把你自己的数据封装到in_array中,假想你的数据构造是your_strcut_t your_struct_t my_own_data; //fill my_own_data ... //放到in_array中,这很关键 g_array_append_vals(in_array66.syxinhao.com, my_own_data, sizeof(your_strcut_t)); //调用general_proxy.h中的dbus接口 client_request(dbus_proxy, api_id, in_array, &out_array, .....); //穿越dbus把数据从到server侧,server侧如何处理,看第四步; //当sever归来数据后,从out_array中取出来就能够了 your_strcut_t* g_array_data = (your_strcut_t*)out_array->data; ..... //free if (in_array) g_free (in_array); if (out_array) g_free (out_array); .... }第四步:告终Server侧,重要是告终general_stub.h中的函数__client_request_cb();
//这个函数的参数很长,除非第一个参数是server对象外,其他的参数能够直接从
general_proxy.h对应的接口参数拷贝到来;该当这个函数和proxy的接口是一对!gboolean
__client_request_cb (ServerObject *server_object, const gint IN_action_id, const gint IN_input_int, const GArray* IN_input_garray, gint* OUT_output_int, GArray** OUT_output_garray, gint* OUT_result, GError **error) { *OUT_output_garray = g_array_new(FALSE, FALSE, sizeof(guint8));//在client侧未曾分配内存,server这里定然要分配 //卸下client侧递交到来的数据 your_strcut_t ×p_data= (your_strcut_t *)&g_array_index(input_garray,your_strcut_t, 0); //对卸下的数据举行处理,看你的过程做什么功能了:) ..... ..... //万一要传回数据到client侧,假想处理过的数据为:your_strcut_t dealed_with_data g_array_append_vals(*output_garray, &dealed_with_data, sizeof(your_strcut_t)); return TRUE;//定然要归来TRUE,否则client侧收不到数据的; }上述通用环节中,1,2在尔后的伸展中,是不要要改的,尤其是第一步,dbus的xml接口描写极其 繁琐;万一为每个API自己去定义xml接口描写,搞不好,client和server之间不通;而且,一段工夫 后,不看dbus的文档,就会淡忘如何写其xml接口;因而做个通用的xml接口描写很省事;
3,4是client/server侧的各自告终,构造是钉死的,无须改多少;一个函数如此,N个函数也是这么;
万一你有30个函数,要离别告终它们吗?无须要,凡是给各自的函数定义其ID就行; 在client/server侧的函数里面搞个switch-case构造就离别了;架构定好了,递交数据也极其得体,比dbus自己的dbus_g_type_struct_set效率高的多,现在开源软件
多用dbus_g_type_struct_set,效率很低,对于递交批量数据,效率很低;万一大家对于如何长进dbus递交消息/数据的效率,有什么更好的见解,迎接沟通。
参看: 一位网友写的dbus的基础的利用,写的不错,大家能够参看: http://blog.csdn.net/yuhang111/archive/2007/08/27/1760141.aspx
另外,dbus的起源在:
http://www.freedesktop.org/wiki/Software/dbus,这里是dbus project的宿主地址, 其官方文档都在这里,大家有空看看;