g_source_set_callback : 无效的回调数据指针

g_source_set_callback : invalid callback data pointer

使用 Glib,我创建了两个 GSource 并注册了相同的回调函数。

并且,将不同的数据指针传递给每个 GSource。

代码如下...

gboolean cb (gpointer data)
{
    printf("data is %d \n", GPOINTER_TO_INT(data));
}

void init_g_source (void)
{
    GSource* src1 = g_timeout_source_new (1000);
    g_source_set_callback (src1, cb, GINT_TO_POINTER(9), NULL);
    g_source_attach (src1, g_main_loop_get_context(mainloop));            
    g_source_unref (src1);

    GIOChannel *ch = g_io_channel_unix_new (socket_fd);        
    GSource* src2 = g_io_create_watch (ch, G_IO_IN);    
    g_source_set_callback (src2, cb, GINT_TO_POINTER(7), NULL);
    g_source_attach (src2, g_main_loop_get_context(mainloop));            
    g_source_unref (src2);  
}

预期结果

然而,实际结果

为什么错误的数据指针只在使用socket_fd的src2中?

  1. 传递了指向局部或全局变量的指针 : 结果是一样的。

  2. 传递了指向内存分配的指针(g_malloc 或 g_new) : 结果是一样的。

  3. 传递了一个 NULL 指针 : 只是数值不同,结果是一样的

g_io_create_watch() 创建的 GSource 运行 GIOFunc 类型的回调函数,而不是 GSourceFunc。 (这在 g_io_add_watch() 的文档中有解释,但在 g_io_create_watch() 的文档中没有提到。)

两个 GSource 需要不同的回调函数:

gboolean cb (gpointer data)
{
    printf("data is %d \n", GPOINTER_TO_INT(data));
}

gboolean cb_io (GIOChannel *source, GIOCondition condition, gpointer data)
{
    printf("data is %d \n", GPOINTER_TO_INT(data));
}

void init_g_source (void)
{
    GSource* src1 = g_timeout_source_new (1000);
    g_source_set_callback (src1, cb, GINT_TO_POINTER(9), NULL);
    g_source_attach (src1, g_main_loop_get_context(mainloop));            
    g_source_unref (src1);

    GIOChannel *ch = g_io_channel_unix_new (socket_fd);        
    GSource* src2 = g_io_create_watch (ch, G_IO_IN);    
    g_source_set_callback (src2, G_SOURCE_FUNC (cb_io), GINT_TO_POINTER(7), NULL);
    g_source_attach (src2, g_main_loop_get_context(mainloop));            
    g_source_unref (src2);  
}