在GTK4的C语言代码中如何正确向g_signal_connect传递结构体?
问题分析与解决
核心原因
你遇到的问题大概率是传入的结构体是局部栈变量:当创建结构体的函数执行完毕后,栈上的内存会被系统释放或覆盖,等按钮触发回调时,你访问的已经是无效内存,所以输出了随机值(这里表现为0)。
解决方案
方案1:动态分配结构体内存(推荐)
用g_malloc()(GTK推荐的内存分配函数)或标准C的malloc()在堆上分配内存,确保回调触发时内存依然有效。记得在窗口销毁时释放内存,避免泄漏。
示例代码:
#include <gtk/gtk.h> typedef struct { int x; int y; } Location; void print_location(GtkWidget *widget, gpointer data) { Location *loc = (Location *)data; g_print("x: %d, y: %d\n", loc->x, loc->y); } // 窗口销毁时释放结构体内存 void on_window_destroy(GtkWidget *widget, gpointer data) { g_free(data); gtk_main_quit(); } int main(int argc, char *argv[]) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *button = gtk_button_new_with_label("Print Location"); // 动态分配结构体内存 Location *loc = g_malloc(sizeof(Location)); loc->x = 1; loc->y = 5; // 绑定按钮点击信号,传入结构体地址 g_signal_connect(button, "clicked", G_CALLBACK(print_location), loc); // 绑定窗口销毁信号,用于释放内存 g_signal_connect(window, "destroy", G_CALLBACK(on_window_destroy), loc); gtk_container_add(GTK_CONTAINER(window), button); gtk_widget_show_all(window); gtk_main(); return 0; }
方案2:使用全局变量(适合快速测试,不推荐大型项目)
把结构体定义为全局变量,这样内存不会随函数执行结束被释放:
#include <gtk/gtk.h> typedef struct { int x; int y; } Location; // 全局结构体,内存生命周期贯穿整个程序 Location loc; void print_location(GtkWidget *widget, gpointer data) { Location *ptr = (Location *)data; g_print("x: %d, y: %d\n", ptr->x, ptr->y); } int main(int argc, char *argv[]) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *button = gtk_button_new_with_label("Print Location"); loc.x = 1; loc.y = 5; g_signal_connect(button, "clicked", G_CALLBACK(print_location), &loc); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_container_add(GTK_CONTAINER(window), button); gtk_widget_show_all(window); gtk_main(); return 0; }
关键注意点
- 绝对不要把局部栈变量的地址传给
g_signal_connect的data参数,除非你能保证回调触发时该变量所在的函数还在运行。 - 用动态内存时,必须在合适的时机(比如窗口销毁)释放内存,否则会造成内存泄漏。
- 回调函数里要正确将
gpointer转换为你的结构体指针类型,类型不匹配也会导致错误输出。
内容的提问来源于stack exchange,提问作者Troglobyte
相关产品推荐
相关产品推荐

