Interface implementation in language bindings
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Subject: Interface implementation in language bindings
- Date: Fri, 25 Feb 2005 17:21:49 -0500
The ideal situation is that someone, using a language binding
to GTK+ could just do:
class Foo (GtkWidget, GtkCellLayout):
def start_editing (event):
[....]
(There is a bit of a problem here in that most languages don't
allow sufficient customization of class initialization to
actually allow such a simple syntax, so mentally add whatever
extra syntax or hacks are necessary)
The problem with the above is that hooking
struct _GtkCellEditableIface
{
GTypeInterface g_iface;
[...]
/* virtual table */
void (* start_editing) (GtkCellEditable *cell_editable,
GdkEvent *event);
};
into a language binding is hard because we need to assign something
to the 'start_editing' vtable pointer. How we fix this once we have
introspection information inside GTK+?
Here's one scheme.
typedef (*GInterfaceDemarshal) (GInterfaceDesc *interface_desc,
GMethodDesc *method_desc,
gpointer instance,
GArgument *args,
GArgument *return_value,
gpointer data);
g_type_add_interface_generic (GType interface_type,
GType iface_type,
GInterfaceDemarshal demarshal,
gpointer data);
The way this works is that
g_type_add_interface_generic (MY_TYPE_FOO, GTK_TYPE_CELL_EDITABLE,
demarshal, data);
Stores GTK_TYPE_CELL_EDITABLE, demarshal, and data off in qdata
associated with MY_TYPE_FOO. Then allocates a structure for
GtkCellEditableIface and fills in start_editing with a pointer
to:
void
_g_generic_demarshal_1 (GTypeInstance *instance);
{
GenericDemarshalData *data;
GArgument *arguments;
GArgument return;
data = lookup_demarshal_data (instance, 1);
/* libffi magic to demarshal to arguments */
demarshal_data_invoke (data, arguments, &return);
/* libffi magic to marshal the return value */
}
We have a big pile of these _1, _2, ... so that we can handle
objects with up to say 256 interface methods that could be
overridden.
You could similarly have a g_type_register_generic() to
handle virtual method overriding in derivation.
A variant of this is to have GGenericDemarshal as an interface you
can add to a type with demarshal_interface, demarshal_object as methods,
and abbreviate g_type_add_interface_generic() to:
g_type_add_interface_generic (GType interface_type,
GType iface_type);
Regards,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]