我有一个需要访问多个GTK小部件的回调函数。为了实现这一点,我试图发送指向打包在结构中的相关GTK小部件的指针作为回调函数的参数(而不是使用全局变量来启用访问)。为了以一种很好的方式构造数据,我使用指向GTK小部件指针结构的指针结构。
我的问题是在尝试读取或写入回调函数中的GTK小部件时出现分段错误。我怎么能避免这个?由于我刚刚开始学习C和GTK,我的方法可能完全不合适,所以我也很感激指出从回调函数访问几个GTK小部件的更一般的问题。
在尝试修复问题时,我设法将代码问题归结为以下问题。更改旋钮的值时会出现段错误。如果让widget_change_value
中的最后一行执行,那么它也会发生段错误。
/* Compile with gcc foo.c `pkg-config --cflags --libs gtk+-2.0` */
#include <gtk/gtk.h> /* Get e.g. via sudo apt-get install libgtk2.0-dev */
typedef struct {
GtkWidget *widget;
} s_input;
typedef struct {
s_input *input;
} s_data;
void widget_change_value(s_data *data) {
/* Segfault when trying to read from data */
int number = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->input->widget));
/* /\* Segfault when trying to write to data *\/ */
/* gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->input->widget), (gdouble) 2.0); */
}
int main(int argc, char *argv[])
{
GtkWidget *window;
s_input input;
s_data data = { &input };
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
input.widget = gtk_spin_button_new_with_range(0, 3, 1);
gtk_container_add(GTK_CONTAINER(window), input.widget);
g_signal_connect(GTK_OBJECT(input.widget), "value_changed", GTK_SIGNAL_FUNC(widget_change_value), (gpointer *) &data);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
答案 0 :(得分:3)
你的崩溃是因为你的回调函数的原型都是错误的。
你有:
void widget_change_value(s_data *data);
但是查看文档,value-changed
信号处理程序回调声明为:
void user_function(GtkSpinButton *spinbutton, gpointer user_data);
您需要添加缺少的小部件指针参数。
此外:
static
,因为它对于它所在的C文件是非常本地的。gpointer
。(gpointer *)
的强制转换是双重错误的,因为您传递的指针(&data
)要转换为gpointer
,不 “指向gpointer
”的指针。星号是错的。但是,正如我上面所说,整个演员阵容毫无意义,应该被删除。GTK_OBJECT()
而不是G_OBJECT()
,GTK_SIGNAL_FUNC()
而不是G_CALLBACK()
。