在DBUS Low-LEVEL的调用中所有的消息都是文本格式的,不存在文本消息到高级语言数据类型转换的问题(即是文本消息到高级语言对象之间的序列化和反序列化的问题)。然而,在DBUS的高级语言绑定类库中,这是首当其冲的一个技术问题。在MeeGo平台上,许多的中间层服务,例如,Tracker service , Gconf,等等从传统的GNome Linux衍生的开源项目所构建的服务通常会使用DBus的GLIB的绑定。而上层的MTF应用则使用QT DBUS绑定。
本文探讨在MeeGo平台上通常会并存的两种DBUS绑定:DBUS-GLIB Binding与QT DBUS Binding之间的传递"aas(字符串二维数组)“ 之间的问题。本文的讨论以一个使用DBUS-GLIB的绑定DBUS的服务器端和一个使用QT DBUS Binding的客户端为调用模型。
服务器端(DBUS-GLIB)使用的DBUS 的XML描述文件相关内容如下:其中GetContacts的返回参数定义为“aas”
<method name="GetContacts">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="my_service_get_contacts"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg type="aas" name="contactList" direction="out" />
</method>
dbus-binding-tool --prefix=my_service --mode=glib-server --output=my-service-glue.h ./my-service.xml 生成相关的函数原型。
客户端(DBUS-QT)对“aas”对应的数据类型是QVector<QStringList> 由于该数据类型的序列化和反序列化逻辑实际上不需要开发者自己开发,可以沿用系统已有的逻辑。进行如下相关的配置之后即可以直接调用服务器端的远程服务。
1.添加声明 Q_DECLARE_METATYPE(QVector<QStringList>)
2.注册QVector<QStringList>数据类型
qRegisterMetaType<QVector<QStringList> >();
qDBusRegisterMetaType<QVector<QStringList> >();
3.相关的dbus调用
QDBusInterface *uservice = new QDBusInterface("cn.com.AAAA.BBBB",
"/cn/com/AAAA/BBBB",
"cn.com.AAAA.BBBB.CCCC", QDBusConnection::sessionBus());
if (!uservice->isValid()) {
qWarning () << "init dbus fail!";
}
QVector<QStringList> dataFromRemote;
QDBusReply< QVector<QStringList> > reply = uservice->call(QDBus::AutoDetect, "GetContacts");
dataFromRemote=reply.value();
4.简单的调用代码如下:
#include <QtDBus>
#include <QStringList>
#include <QDebug>
#include <QCoreApplication>
#include <glib.h>
#include <QtDBus/QDBusMetaType>
#include <QtCore/QMetaType>
#include <QtDBus/QtDBus>
Q_DECLARE_METATYPE(QVector<QStringList>)
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QDBusInterface *uservice = new QDBusInterface("cn.com.AAAA.BBBB",
"/cn/com/AAAA/BBBB",
"cn.com.AAAA.BBBB.CCCC", QDBusConnection::sessionBus());
if (!uservice->isValid()) {
qWarning () << "init dbus fail!";
}
QVector<QStringList> dataFromRemote;
QDBusReply< QVector<QStringList> > reply = uservice->call(QDBus::AutoDetect, "GetContacts");
dataFromRemote=reply.value();
......
关于Q_DECLARE_METATYPE与qRegisterMetaType 的具体关系,请参见:
http://hi.baidu.com/cyclone/blog/item/01108bd40599b00fa18bb793.html
而int qDBusRegisterMetaType (),文档上说:Registers T with the QtDBus type system and the Qt meta-type system , if it's not already registered. 因此可以认为qDBusRegisterMetaType ()包含qRegisterMetaType的功能,尝试在上述代码中去掉qRegisterMetaType,程序是一样可以正常运行的。