You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GtkSwitch回调访问传入数据时触发段错误的原因排查

GtkSwitch回调段错误的原因及解决

问题背景

在Glade中为GTK-3.24项目添加了GtkSwitch控件,无编译警告,将自定义MyData结构体作为用户数据传入on_switch1_state_set信号回调。相关代码如下:

main.h

typedef struct _MyData MyData;
struct _MyData {
  GtkWidget *switch1;
  int value;
}; // 注:原代码此处缺失分号,建议补上

int on_switch1_state_set (GtkSwitch *, MyData *);

main.c

data->switch1 = GTK_WIDGET (gtk_builder_get_object (builder, "switch1"));
data->value = 0;

callbacks.c

int on_switch1_state_set (GtkSwitch *switch1, MyData *data) {

  fprintf (stdout, "%i\n", data->value);
  
  return (EXIT_SUCCESS);
}

出现的问题:回调执行到访问data->value时触发段错误,但仅打印字符串无异常;其他控件(输入框、复选框)的回调操作该结构体均正常,仅GtkSwitch出现此问题。

核心原因

GTK信号的回调参数有严格的固定顺序,GtkSwitch的state-set信号自带一个额外的gboolean类型参数(切换后的状态值),你的回调函数漏掉了这个参数,导致参数解析完全错位:

  • 实际传入的用户数据指针被错误地当成了gboolean类型的状态值(0或1)
  • 回调里的data变量实际是个无效的小数值,把它当成指针去访问data->value必然触发段错误

对比其他控件(如复选框的toggled信号),这类信号没有额外参数,所以你的回调参数顺序是正确的,能正常访问结构体;但state-set信号的标准签名为:

gboolean on_switch_state_set(GtkSwitch *switch_widget, gboolean state, gpointer user_data);

解决方法

修改回调函数的参数列表,补上gboolean state参数,并修正返回值类型(严格遵循GTK信号回调的签名要求):

修正后的callbacks.c

gboolean on_switch1_state_set (GtkSwitch *switch1, gboolean state, MyData *data) {

  fprintf (stdout, "%i\n", data->value);
  // 如需处理开关状态,可使用state变量:
  // fprintf(stdout, "开关状态:%s\n", state ? "开启" : "关闭");
  
  return TRUE; // 返回TRUE表示已处理信号,阻止默认行为;返回FALSE则让GTK执行默认处理逻辑
}

同时更新main.h中的函数声明:

gboolean on_switch1_state_set (GtkSwitch *, gboolean, MyData *);

另外,记得补上main.h中结构体定义末尾的分号,避免潜在编译问题。

内容的提问来源于stack exchange,提问作者Dave Buchan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:15:34