如何在循环中使用 gtk 信号发送 user_data

How to send user_data with gtk signals in loop

我在主线程的核心 class 中注册了信号 "make" 和 "send"。我在同一线程中从用户 class 调用 call_make()call_make() 将做一些工作并从工作线程获取一些数据,在 return 之后它将发出信号 "make"。

这是用户代码class

struct my_struct{
   int cur_make_id;
   int cur_send_id;    //there may be many id's if multiple signals
}

void on_send_cb(core, gpointer data){
   my_struct *user_data = (my_struct *) data;
   printf("cure_make_id %d", user_data->cur_make_id);   \ this prints "4" everytime  
   printf("cure_send_id %d", user_data->cur_send_id);   \ this prints "2" everytime  
}

void on_make_cb(core, gpointer data){
   my_struct *user_data = (my_struct *) data;
   printf("cure_make_id %d", user_data->cur_make_id);   \ this prints "4" everytime  
   for(int index=0;index<3;index++){
       call_send();
       user_data->cur_send_id = index;
       g_signal_connect(core, "send", G_CALLBACK(on_send_cb), user_data );
   }     
}

void function(){
   my_struct *user_data = g_malloc0(sizeof(my_struct));
   for(int index=0;index<5;index++){
       call_make();
       user_data->cur_make_id = index;
       g_signal_connect(core, "make", G_CALLBACK(on_make_cb), user_data );
   }
}

我对所有信号都弄错了 cur_make_id 和 cur_send_id(获取 for 循环的最后一个索引)

我知道 signal_emit 并延迟连接并且 for 循环向前移动。我想知道如何将这个 user_data 分享给回调,以便我知道这个回调是针对哪个索引?

(为简单起见,我制作了这些 call_make() api,我无法更改 api 的参数)

假设您只是在谈论连接回调期间提供的 user_data,您的内存分配有误:

void function(){
   my_struct *user_data = g_malloc0(sizeof(my_struct));
   for(int index=0;index<5;index++){
       call_make();
       user_data->cur_make_id = index;
       g_signal_connect(core, "make", G_CALLBACK(on_make_cb), user_data );
   }
}

在此函数中,您只有 1 个内存块传递给所有连接的回调函数。每当调用回调时,它们都会看到最后写入的内容。 在您的情况下,这将是 index=4.

为不同的handler提供不同的数据,其实需要分配不同的数据:

void function(){
   for(int index=0;index<5;index++){
       my_struct *user_data = g_malloc0(sizeof(my_struct));
       call_make();
       user_data->cur_make_id = index;
       g_signal_connect(core, "make", G_CALLBACK(on_make_cb), user_data);
   }
}

如果您在从触发信号的函数中提供数据时也遇到问题,则需要显示更多代码。