之前曾经详细看过在DBUS GLIB BINDING中本地消息(Signal)如何映射到DBUS消息(Signal),最近再次研究DBUS 的GLIB,发现尚遗漏了DBus消息如何映射成本地方法调用的重要一环。此处补上。为了比较通透了解文本消息到函数调用的动态类型绑定实现过程,下载了 DBUS、DBUS-GLIB、以及以Embed EDS的为研究入口。由于不同的版本代码可能有差异,下面着重说明其原理。本文记录仅仅以代码阅读为基础进行梳理,并未进行详细的程序执行验证。
1、 预编译生成的函数类型结构信息分析。
DBUS GLIB的用法,首先是使用dbus-binding-tool,将DBus对象接口描述的XML文件生成动态函数类型绑定的信息。这里不详细的说用法,网上有大量的资料。下面以e-data-book-factory为例看看生成的函数类型结构信息
vi e-data-book-factory-glue.h
static const DBusGMethodInfo dbus_glib_e_data_book_factory_methods[] = {
{ (GCallback) impl_BookFactory_getBook, dbus_glib_marshal_e_data_book_factory_NONE__STRING_POINTER, 0 },
};
impl_BookFactory_getBook为本地调用的业务方法,dbus_glib_marshal_e_data_book_factory_NONE__STRING_POINTER为远程DBUS文本消息映射到本地调用方法需要用到的反序列化函数。
const DBusGObjectInfo dbus_glib_e_data_book_factory_object_info = {
0,
dbus_glib_e_data_book_factory_methods,
1,
"org.gnome.evolution.dataserver.addressbook.BookFactory/0getBook/0A/0source/0I/0s/0path/0O/0F/0N/0o/0/0/0",
"/0",
"/0"
};
DBusGObjectInfo 与DBusGMethodInfo在./dbus-glib.h中定义:
vi ./dbus-glib.h
typedef struct _DBusGObjectInfo DBusGObjectInfo;
typedef struct _DBusGMethodInfo DBusGMethodInfo;
struct _DBusGMethodInfo
{
GCallback function;
GClosureMarshal marshaller;
int data_offset;
};
struct _DBusGObjectInfo
{
int format_version;
const DBusGMethodInfo *method_infos;
int n_method_infos;
const char *data;
const char *exported_signals;
const char *exported_properties;
};
这里补充一句data_offset的用法,_DBusGObjectInfo 中的object->data + method->data_offset获得的地址,才是对method的描述,请看这个函数(dbus-gobject.c)
static const char *
get_method_data (const DBusGObjectInfo *object,
const DBusGMethodInfo *method)
{
return object->data + method->data_offset;
}
这里补充一个具有多个DBUS函数调用的对象例子,仅仅为了说明 data_offset的用法,清楚则可以跳过。
static const DBusGMethodInfo dbus_glib_e_data_book_methods[] = {
{ (GCallback) impl_AddressBook_Book_open, dbus_glib_marshal_e_data_book_NONE__BOOLEAN_POINTER, 0 },
......
{ (GCallback) impl_AddressBook_Book_close, dbus_glib_marshal_e_data_book_NONE__POINTER, 1275 },
};
const DBus