mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-02 02:40:07 +02:00
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
This commit is contained in:
parent
bb7f8d57c2
commit
67358cdaf4
@ -216,15 +216,28 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info,
|
|||||||
GType implementor_gtype,
|
GType implementor_gtype,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
GIBaseInfo *container_info;
|
||||||
|
GIInterfaceInfo *interface_info;
|
||||||
GIObjectInfo *object_info;
|
GIObjectInfo *object_info;
|
||||||
GIStructInfo *struct_info;
|
GIStructInfo *struct_info;
|
||||||
GIFieldInfo *field_info = NULL;
|
GIFieldInfo *field_info = NULL;
|
||||||
int length, i, offset;
|
int length, i, offset;
|
||||||
gpointer implementor_vtable;
|
gpointer implementor_class, implementor_vtable;
|
||||||
gpointer func = NULL;
|
gpointer func = NULL;
|
||||||
|
|
||||||
object_info = (GIObjectInfo *) g_base_info_get_container (vfunc_info);
|
container_info = g_base_info_get_container (vfunc_info);
|
||||||
struct_info = g_object_info_get_class_struct (object_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);
|
length = g_struct_info_get_n_fields (struct_info);
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
@ -250,10 +263,23 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info,
|
|||||||
goto out;
|
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);
|
offset = g_field_info_get_offset (field_info);
|
||||||
func = *(gpointer*) G_STRUCT_MEMBER_P (implementor_vtable, offset);
|
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);
|
g_base_info_unref (field_info);
|
||||||
|
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user