DBUS-GLIB:从DBUS文本消息到函数调用背后的机制

博客介绍了DBUS GLIB如何将DBUS消息映射为本地方法调用的过程。首先,通过dbus-binding-tool生成动态函数类型绑定信息,如e_data_book_factory-glue.h中的DBusGMethodInfo结构体。接着,这些信息在对象的类初始化函数中被记住。在主函数启动时,对象向DBus注册。当DBUS消息到达时,通过DBusObjectPathVTable的message_function处理,查找并调用相应的本地方法。
摘要由CSDN通过智能技术生成

之前曾经详细看过在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

`g_dbus_proxy_call_sync` 是 GLib 库中用于同步调用 D-Bus 代理对象方法的函数。它允许您在 D-Bus 上进行同步的方法调用,并等待方法调用的完成。 函数原型如下: ```c gboolean g_dbus_proxy_call_sync (GDBusProxy *proxy, const gchar *method_name, GVariant *parameters, GDBusCallFlags flags, gint timeout_msec, GCancellable *cancellable, GError **error); ``` 参数说明: - `proxy`:要调用方法的 D-Bus 代理对象。 - `method_name`:要调用的方法名称。 - `parameters`:方法调用的参数,使用 GVariant 类型。 - `flags`:调用标志,可以是 `G_DBUS_CALL_FLAGS_NONE` 或其他标志。 - `timeout_msec`:超时时间(以毫秒为单位),如果设置为 -1,则表示不设置超时。 - `cancellable`:可选的 GCancellable 对象,用于取消方法调用。 - `error`:如果发生错误,将在此处返回错误信息。 函数返回值为 `gboolean` 类型,表示方法调用是否成功。如果成功,返回 `TRUE`,否则返回 `FALSE`。 使用 `g_dbus_proxy_call_sync` 函数时,首先需要获取一个 D-Bus 代理对象,可以使用 `g_dbus_proxy_new_sync` 函数来创建。然后,通过调用 `g_dbus_proxy_call_sync` 来执行同步的方法调用。 这个函数可以方便地与 D-Bus 服务进行通信,但需要注意的是,它会阻塞当前线程,直到方法调用完成或超时。如果需要异步的方法调用,可以考虑使用 `g_dbus_proxy_call` 函数。 您可以参考 GLib 的文档以获取更详细的信息和示例代码:[GLib D-Bus API 文档](https://developer.gnome.org/gio/stable/gdbus-proxy.html#g-dbus-proxy-call-sync) 希望这能帮助到您!如果你有更多问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值