使用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);
答案 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,这将更容易弄清楚示例代码的问题是什么。