Help understanding scope of 'C' variables GTK app [noob]

Pertinent code in file ‘main.c’:

**// I understand this**
typedef struct {
    GtkWidget *w_rb_1;
    GtkWidget *w_rb_2;
    GtkWidget *w_rb_5;
    GtkWidget *w_lbl_choice;
} app_widgets;

int main()
{
**// I understand this allocation**
    app_widgets     *widgets = g_slice_new(app_widgets);

**// I understand this pointer assignments**
    widgets->w_rb_1 = GTK_WIDGET(gtk_builder_get_object(builder, "rb_1"));
    widgets->w_rb_2 = GTK_WIDGET(gtk_builder_get_object(builder, "rb_2"));
    widgets->w_rb_5 = GTK_WIDGET(gtk_builder_get_object(builder, "rb_5"));
    widgets->w_lbl_choice = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_choice"));

**// understood about freeing**
    g_slice_free(app_widgets, widgets);
}

void on_btn_read_clicked (GtkButton *button, app_widgets *widgets)
{
**// NOW I'm scratching my head.  How did the app_widgets struct defined (not global) in main()**
**// become attached as this function's parameter??**
}

Thx.

That code seems incomplete. Try looking for a g_signal_connect() which passes it on. Or it could be in your builder file.

@jensgeorg:

Thanks for replying. As it happens, in the full source there is no g_signal_connect().

Asking a different way, let’s pretend main() contained:

int main()
{
app_widgets *widgets = g_slice_new(app_widgets);

on_btn_read_clicked (button, widgets);

g_slice_free(app_widgets, widgets);
}

void on_btn_read_clicked (GtkButton *button, app_widgets *widgets)
{
}

This would make complete sense to me, because WITHIN MAIN(), function on_btn_read_clicked() is called with MAIN()'s private WIDGETS structure in the function call.

I just don’t get how a (private) variable (structure) scope can simply jump out of main() as it does in my original code snippet.

Thx.

GObject’s signal call-backs allow you to pass an arbitrary pointer when connecting, cf. https://developer.gnome.org/gobject/stable/howto-signals.html

on_btn_read_clicked looks like such as callback.

What you would usually do (within main()) is
g_signal_connect (G_OBJECT(btn_read), "clicked", G_CALLBACK (on_btn_read_clicked), widgets)

Also, widgets is dynamically allocated (g_slice_alloc() is basically a fancy malloc(), see https://developer.gnome.org/glib/stable/glib-Memory-Slices.html), so it is not bound to call scope anyway.

The app_widgets pointer isn’t really attached to the function in the way you think. The button-click event calls a function with a pointer to a GtkButton and a pointer to something. It doesn’t care what that something is, you can pass in any pointer you like when you setup the callback. The function actually takes a void* type which, for C, means pointer to no specific thing.

This also means that you could pass in a pointer to one kind of thing when the function is expecting another kind of thing, and that can cause all sorts of bugs. That’s a freedom which C allows you, and the risk it carries.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.