diff options
author | Giovanni Campagna <gcampagna@src.gnome.org> | 2013-10-13 02:02:22 +0200 |
---|---|---|
committer | Giovanni Campagna <gcampagna@src.gnome.org> | 2013-10-22 23:33:44 +0200 |
commit | f7acdd34e28456d706a38e51b8332569d7a0f271 (patch) | |
tree | 4d2409b92dde465818c8f9505af31e0e6ad21fbb /girepository/givfuncinfo.c | |
parent | 79dd24a4375ab6497aec193a8505dea555b33023 (diff) | |
download | gobject-introspection-f7acdd34e28456d706a38e51b8332569d7a0f271.tar.gz |
GIVFuncInfo: allow retrieving the address of an interface vfunc
Don't assume that the parent of a GIVFuncInfo is a GIObjectInfo,
it could be a GIInterfaceInfo, if the vfunc is part of interface
instead of a class.
https://bugzilla.gnome.org/show_bug.cgi?id=688375
Diffstat (limited to 'girepository/givfuncinfo.c')
-rw-r--r-- | girepository/givfuncinfo.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/girepository/givfuncinfo.c b/girepository/givfuncinfo.c index eaf523d2..8a5b71a1 100644 --- a/girepository/givfuncinfo.c +++ b/girepository/givfuncinfo.c @@ -216,15 +216,28 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, GType implementor_gtype, GError **error) { + GIBaseInfo *container_info; + GIInterfaceInfo *interface_info; GIObjectInfo *object_info; GIStructInfo *struct_info; GIFieldInfo *field_info = NULL; int length, i, offset; - gpointer implementor_vtable; + gpointer implementor_class, implementor_vtable; gpointer func = NULL; - object_info = (GIObjectInfo *) g_base_info_get_container (vfunc_info); - struct_info = g_object_info_get_class_struct (object_info); + container_info = g_base_info_get_container (vfunc_info); + if (g_base_info_get_type (container_info) == GI_INFO_TYPE_OBJECT) + { + object_info = (GIObjectInfo*) container_info; + interface_info = NULL; + struct_info = g_object_info_get_class_struct (object_info); + } + else + { + interface_info = (GIInterfaceInfo*) container_info; + object_info = NULL; + struct_info = g_interface_info_get_iface_struct (interface_info); + } length = g_struct_info_get_n_fields (struct_info); for (i = 0; i < length; i++) @@ -250,10 +263,23 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, goto out; } - implementor_vtable = g_type_class_ref (implementor_gtype); + implementor_class = g_type_class_ref (implementor_gtype); + + if (object_info) + { + implementor_vtable = implementor_class; + } + else + { + GType interface_type; + + interface_type = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) interface_info); + implementor_vtable = g_type_interface_peek (implementor_class, interface_type); + } + offset = g_field_info_get_offset (field_info); func = *(gpointer*) G_STRUCT_MEMBER_P (implementor_vtable, offset); - g_type_class_unref (implementor_vtable); + g_type_class_unref (implementor_class); g_base_info_unref (field_info); if (func == NULL) |