複数の 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;
}