没有mainloop的GLIB用法

时间:2014-05-19 12:28:19

标签: c glib dbus gdbus

使用Glib时遇到问题。我想订阅一个dbus信号而不用 g_main_loop_run 启动主循环。

我创建了与正确总线的连接,并调用函数 g_dbus_connection_signal_subscribe

我将主函数中的 g_main_loop_run 的调用替换了一会儿(1)。

不幸的是,它不起作用。如果我理解正确的GLib,则无需启动主循环进行此类处理。

请帮忙。

示例代码:

session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION,
                             NULL,
                             NULL );


g_dbus_connection_signal_subscribe(session_bus,
                                   "org.freedesktop.Notifications",
                                   "org.freedesktop.Notifications",
                                   "NotificationClosed",
                                   "/org/freedesktop/Notifications",
                                   NULL,
                                   G_DBUS_SIGNAL_FLAGS_NONE,
                                   (GDBusSignalCallback) onNotifClosed,
                                   NULL,
                                   NULL );

loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
g_main_loop_unref(loop);
g_object_unref(session_bus);

3 个答案:

答案 0 :(得分:4)

  

如果我理解正确的GLib,则无需启动   主要用于此类治疗。

如果要等待传入的DBus事件,则必须运行主循环。主循环的作用是等待和处理事件,并且您希望等待然后处理事件。作为g_main_loop_run的替代方案,您可以尝试在g_main_context_iteration中投放while(1)

答案 1 :(得分:1)

我同样需要以非阻塞方式处理GLib事件,而且我在任何地方都找不到完整的答案,因此我在这里发布了我的解决方案以供参考。

正如el.pescado所说,g_main_loop_run()的一种替代方法是在g_main_context_iteration()对象的上下文中反复调用GMainLoop。例如,这可以循环执行,从而允许在事件处理周期之间执行某些intervening_task()直到遇到某种termination_condition()

GMainLoop *loop = g_main_loop_new();
while (!termination_condition())
{
  g_main_context_iteration(g_main_loop_get_context(loop), FALSE);
  intervening_task();
}

g_main_loop_unref(loop);

在上面的代码段中,循环上下文由g_main_loop_get_context()检索,所有未决的GLib事件由g_main_context_iteration()处理。将may_block参数设置为FALSE会导致该函数在没有任何未决事件的情况下立即返回(否则它将阻止等待处理的事件)。

但是,值得注意的是,如果以上就是您想做的,那么您最好还是坚持使用g_main_loop_run()并使用g_timeout_add()g_idle_add()来注册介入的任务和终止条件作为事件回调-后者将调用g_main_loop_quit()终止循环。这里的重点不是按原样使用该代码,而只是演示如何以非阻塞方式处理GLib事件,因此可以将其集成到另一个框架的主循环中。例如Qt或ROS。

答案 2 :(得分:-2)

它对我有用:

#include <glib.h>
#include <gio/gio.h>

static GMainLoop* loop = NULL;

static void
onNotifClosed (GDBusConnection* connection,
               const gchar* sender_name,
               const gchar* object_path,
               const gchar* interface_name,
               const gchar* signal_name,
               GVariant* parameters,
               gpointer user_data) {
  g_message ("Works for me.");
  g_main_loop_quit (loop);
}


int
main(int argc, char *argv[])
{
  GDBusConnection* conn = NULL;

  loop = g_main_loop_new (NULL, FALSE);

  conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  g_assert (conn != NULL);

  g_dbus_connection_signal_subscribe (conn,
                                      "org.freedesktop.Notifications",
                                      "org.freedesktop.Notifications",
                                      "NotificationClosed",
                                      "/org/freedesktop/Notifications",
                                      NULL,
                                      G_DBUS_SIGNAL_FLAGS_NONE,
                                      onNotifClosed,
                                      NULL,
                                      NULL);

  loop = g_main_loop_new (NULL, FALSE);

  g_main_loop_run (loop);

  g_main_loop_unref (loop);
  g_object_unref (conn);

  return 0;
}

如果代码实际编译在未来,你应该考虑发布short, self contained, correct examples,这将更容易弄清楚示例代码的问题是什么。