特に、特定の関数のみがそれらを変更できるようにしたい場合は、グローバルに注意するのは正しいことです。
より多くのデータを保持していると仮定するとA
(簡単にするために と定義しましたint
)、使い慣れた方法で構造をセットアップできます。
typedef struct t_MYCBSD
{
int A;
// other members
} MYCBSD; // callback struct data
必要に応じて他のデータ メンバーを含めます。t_MYCBSD
(自己参照がある場合に備えて含めました)。
その後、次のようにコールバック関数を実装できます。
void callback_func1( GtkWidget *widget, gpointer user_data )
{
MYCBSD *data = user_data;
data->A = some_func();
}
void callback_func2( GtkWidget *widget, gpointer user_data )
{
MYCBSD *data = user_data;
data->A = another_func();
}
void callback_func3( GtkWidget *widget, gpointer user_data )
{
MYCBSD *data = user_data;
if( data->A > threshold ) do_something();
else do_nothing();
}
明らかに、some_func()
、another_func()
、threshold
、do_something()
およびdo_nothing()
は、このコンテキストで有効です。
注:構造体へのdata
ポインターにより、構文がもう少し明確になります。以下も使用できます。
((MYCBSD *) user_data)->A = some_func();
いずれにしても、通常、ウィジェットを作成するときにコールバックを設定します。次の (大幅に選別された、GtkBuilder 以外の) コードでMYCBSD mydata
は、ローカルにスコープが設定されます。「クリック」イベントでいくつかのボタンにコールバックが設定されると想定しています。
int main( int argc, char* argv[] )
{
MYCBSD mydata;
// Below-referenced widgets
GtkWidget *mywidget1, *mywidget2, *mywidget3;
// ... other widgets and variables
mydata.A = 0; // Optionally set an initial value to A
// Standard init via gtk_init( &argc, &argv );
// ... Create the toplevel and a container of some kind
// Create mywidget1,2,3 (as buttons, for example)
mywidget1 = gtk_button_new_with_label ("widget1");
mywidget2 = gtk_button_new_with_label ("widget2");
mywidget1 = gtk_button_new_with_label ("widget3");
g_signal_connect( mywidget1, "clicked", G_CALLBACK(callback_func1), &mydata );
g_signal_connect( mywidget2, "clicked", G_CALLBACK(callback_func2), &mydata );
g_signal_connect( mywidget3, "clicked", G_CALLBACK(callback_func3), &mydata );
// ... Attach those widgets to container
// ... and show all
// Run the app in a standard way via gtk_main();
return 0;
}
ここで重要な行は次のとおりです。
g_signal_connect( mywidget1, "clicked", G_CALLBACK(callback_func1), &mydata );
g_signal_connect( mywidget2, "clicked", G_CALLBACK(callback_func2), &mydata );
g_signal_connect( mywidget3, "clicked", G_CALLBACK(callback_func3), &mydata );
最後のパラメーターは、データをコールバック関数に渡します。
単一の値のみを共有しA
たい場合は、構造体を必要とせずに同様の方法で渡すことができます。