From: <bug...@bu...> - 2004-12-16 13:12:34
|
http://bugzilla.gnome.org/show_bug.cgi?id=161012 gnome-perl | Gtk2 | Ver: unspecified ------- Additional Comments From sc...@as... 2004-12-16 08:12 ------- While GObject is reference-counted and therefore can be better managed for lifetime, passing a GObject pointer where a GtkTreeIter pointer is wanted is pretty dangerous. I would imagine that the only reason you got away with it is that since GtkTreeIter is just a plain struct, gtk+ can't do sanity checks on it and so doesn't (it contains no type id). Even though you created a GObject with stamp and user_data fields, the compiler will not find them at the safe struct offset, so code compiled to work with a real GtkTreeIter will fail mysteriously with a GObject --- it will think that the GObject's type id is the stamp, for example. Furthermore, while gtk+ does no type checks on GtkTreeIters, the bindings expect that they are plain structs to be treated as GBoxed types, and will do the exactly wrong thing to a GObject pointer. Let's track a call to gtk_tree_model_get_value() through both C and perl to see what i mean: C: you've passed a GObject * to gtk_tree_model_get_value() for the iter. gtk_tree_model_get_value() checks that iter != NULL. This is true. gtk_tree_model_get_value() calls get_value() vfunc from your model's iface. This actually calls a function in your custom model, which expects a GObject, so things mostly work. If you passed it to a built-in model, however, it would eventually cause a segfault when gtk+ tried to use the bogus data. Perl: you attempt to pass a Glib::Object reference to Gtk2::TreeModel::get() Gtk2::TreeModel::get() calls SvGtkTreeIter() to fetch the pointer from the reference in ST(1). SvGtkTreeIter() is a macro (defined in gperl-autogen.h) that evaluates to gperl_get_boxed_check((sv), GTK_TYPE_TREE_ITER)). GTK_TYPE_TREE_ITER is a boxed type id, and gperl_get_boxed_check() will look up the registered boxed wrapper (the default, in this case), which assumes that the SV points to a wrapper struct containing the type id, a boolean saying whether the wrapper owns the struct, and a pointer to the struct; however, you've actually passed a magical GObject reference. The wrapper class's unwrap vfunc, in this case default_boxed_unwrap() in in Glib/GBoxed.xs, calls sv_derived_from() to verify that the reference is blessed into the package associated with GTK_TYPE_TREE_ITER, "Gtk2:: TreeIter". However, your type is derived from Glib::Object, so this check will fail with the message "MyFoo is not of type Gtk2::TreeIter". That is, you can't even get through the bindings to pass the wrong thing. So, i don't think using a GObject for the iter will help. ------- You are receiving this mail because: ------- You are the assignee for the bug. |