summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2013-10-13 02:02:22 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2013-10-22 23:33:44 +0200
commitf7acdd34e28456d706a38e51b8332569d7a0f271 (patch)
tree4d2409b92dde465818c8f9505af31e0e6ad21fbb
parent79dd24a4375ab6497aec193a8505dea555b33023 (diff)
downloadgobject-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
-rw-r--r--girepository/givfuncinfo.c36
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)