Adel Ahmed
Adel Ahmed

Reputation: 638

passing multiple arguments to a gtk callback function

I'm trying to pass multiple arguments to a gtk call back function I have the following code so far:

void add_new_set(GtkDialog *dialog, gint response_id, gpointer callback_params)
{
  g_print (gtk_entry_get_text (((struct data *) callback_params)->entry));
}

struct data callback_params;
    callback_params.entry = gtk_entry_new();
    gtk_container_add(GTK_CONTAINER(content_area), callback_params.entry);
    g_signal_connect(dialog,"response",G_CALLBACK (add_new_set),&callback_params);

nothing get g_print ed I get teh following error instead: (tat:5918): Gtk-CRITICAL **: IA__gtk_entry_get_text: assertion 'GTK_IS_ENTRY (entry)' failed

(tat:5918): GLib-CRITICAL **: g_print: assertion 'format != NULL' failed

I'm open to using techniques other than passing a struct pointer

thanks

Upvotes: 2

Views: 2231

Answers (1)

You practically need to pack the composite data in a heap-allocated struct, and pass the pointer to the callback.

struct data *cb_data = g_new0(struct data, 1);
cb_data->entry = gtk_entry_new();
cb_data->foo = "somefoo";
g_signal_connect(dialog,"response",G_CALLBACK (add_new_set), cb_data);

But you might instead have a single static variable of some struct type, and pass the address of that variable to your callback. This is usually bad practice and I don't recommend coding like this (since you want a callback to be somehow reentrant).

You cannot take the address of a local variable and pass it to g_signal_connect (because GTK signal handling will use that pointer long after you have returned from your function so popped its call frame).

Of course, the issue is when should your program free that cb_data. Perhaps consider g_signal_connect_data which has a destroy_data closure notification. Or connect another signal to free that data (perhaps widget "destroy" or dialog "close" on your dialog ....).

You should consider using valgrind to debug memory leaks.

Upvotes: 3

Related Questions