I need to make a macro to typecast (right word?) pointer struct from a function parameter. This is my struct:
typedef struct _AppData {
GtkWidget* toplevel; // main window
GtkWidget* view; // column style view
GtkWidget* entry_outdir; // output dir
GtkWidget* entry_artist; // artist
GtkWidget* entry_title; // title
GtkWidget* entry_link; // link
GtkWidget* check_jman; // bool for jman
GtkWidget* menuitem_clear; // init states
GtkWidget* menuitem_action; // play/stop menu item
} AppData, *PAppData;
somewhere in my code is used like this:
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_select_folder), pad);
void cb_select_folder (GtkButton* sender, gpointer user_data)
{
PAppData pad = PAPPDATA(user_data); // typecast macro here
const gchar* dirname = gtk_entry_get_text (GTK_ENTRY(pad->entry_outdir));
// ..
}
To create the macro I'm trying this:
#define PAPPDATA(_in_) (PAppData(_in_))
and I get error: expected ‘)’ before ‘user_data’ Any help?
In C you don't have to cast a (void*) to it's final type. When using glib, gpointer is a typedef for a void*. Hence, no casting is nessesary. You do need to be sure, that the type is correct, otherwise you're in trouble.
void cb_select_folder (GtkButton* sender, gpointer user_data)
{
PAppData pad = user_data; // No cast Necessary.
const gchar* dirname = gtk_entry_get_text (GTK_ENTRY(pad->entry_outdir));
// ..
}
The GTK_ENTRY(pad->entry_outdir), actually does a cast, but that is because it's casting between two different kinds of pointers, from GtkWidget*
to GtkEntry*
. In addition to the cast, It also does some runtime checking whether the GtkWidget*
is actually a GtkEntry*
, you probably get a runtime warning when doing this cast when pad->entry_outdir
turns out to be pointing to something else than a GtkEntry. But in GObject speak, GtkEntry
is a GtkWidget
and GtkWidget
is an GObject
. You PAppData is a plain pointer to struct and not a GObject.