mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-16 12:28:48 +02:00
Add support for instance-private data. g_type_class_add_private(),
Thu Feb 27 17:33:19 2003 Owen Taylor <otaylor@redhat.com> * gtype.[ch] testgobject.c: Add support for instance-private data. g_type_class_add_private(), g_type_instance_get_private(), G_TYPE_INSTANCE_GET_PRIVATE(). (#101959, patch partly by Mark McLoughlin, extensive feedback from Tim Janik.)
This commit is contained in:
parent
e6d15f6eaf
commit
c2a431c894
@ -1,3 +1,10 @@
|
|||||||
|
Thu Feb 27 17:33:19 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtype.[ch] testgobject.c: Add support for instance-private data.
|
||||||
|
g_type_class_add_private(), g_type_instance_get_private(),
|
||||||
|
G_TYPE_INSTANCE_GET_PRIVATE(). (#101959, patch partly by
|
||||||
|
Mark McLoughlin, extensive feedback from Tim Janik.)
|
||||||
|
|
||||||
2003-03-06 Matthias Clasen <maclas@gmx.de>
|
2003-03-06 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* gsignal.c (g_signal_handlers_block_matched):
|
* gsignal.c (g_signal_handlers_block_matched):
|
||||||
|
151
gobject/gtype.c
151
gobject/gtype.c
@ -107,6 +107,18 @@ static GStaticRWLock type_rw_lock = G_STATIC_RW_LOCK_INIT;
|
|||||||
sizeof (gpointer)), \
|
sizeof (gpointer)), \
|
||||||
sizeof (glong)))
|
sizeof (glong)))
|
||||||
|
|
||||||
|
/* The 2*sizeof(size_t) alignment here is borrowed from
|
||||||
|
* GNU libc, so it should be good most everywhere.
|
||||||
|
* It is more conservative than is needed on some 64-bit
|
||||||
|
* platforms, but ia64 does require a 16-byte alignment.
|
||||||
|
* The SIMD extensions for x86 and ppc32 would want a
|
||||||
|
* larger alignment than this, but we don't need to
|
||||||
|
* do better than malloc.
|
||||||
|
*/
|
||||||
|
#define STRUCT_ALIGNMENT (2 * sizeof (gsize))
|
||||||
|
#define ALIGN_STRUCT(offset) \
|
||||||
|
((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)
|
||||||
|
|
||||||
|
|
||||||
/* --- typedefs --- */
|
/* --- typedefs --- */
|
||||||
typedef struct _TypeNode TypeNode;
|
typedef struct _TypeNode TypeNode;
|
||||||
@ -182,6 +194,10 @@ struct _TypeNode
|
|||||||
#define iface_node_set_dependants_array_W(n,d) (type_set_qdata_W ((n), static_quark_dependants_array, (d)))
|
#define iface_node_set_dependants_array_W(n,d) (type_set_qdata_W ((n), static_quark_dependants_array, (d)))
|
||||||
#define TYPE_ID_MASK ((GType) ((1 << G_TYPE_FUNDAMENTAL_SHIFT) - 1))
|
#define TYPE_ID_MASK ((GType) ((1 << G_TYPE_FUNDAMENTAL_SHIFT) - 1))
|
||||||
|
|
||||||
|
#define NODE_IS_ANCESTOR(ancestor, node) \
|
||||||
|
((ancestor)->n_supers <= (node)->n_supers && \
|
||||||
|
(node)->supers[(node)->n_supers - (ancestor)->n_supers] == NODE_TYPE (ancestor))
|
||||||
|
|
||||||
|
|
||||||
struct _IFaceHolder
|
struct _IFaceHolder
|
||||||
{
|
{
|
||||||
@ -229,6 +245,7 @@ struct _InstanceData
|
|||||||
gconstpointer class_data;
|
gconstpointer class_data;
|
||||||
gpointer class;
|
gpointer class;
|
||||||
guint16 instance_size;
|
guint16 instance_size;
|
||||||
|
guint16 private_size;
|
||||||
guint16 n_preallocs;
|
guint16 n_preallocs;
|
||||||
GInstanceInitFunc instance_init;
|
GInstanceInitFunc instance_init;
|
||||||
GMemChunk *mem_chunk;
|
GMemChunk *mem_chunk;
|
||||||
@ -909,6 +926,13 @@ type_data_make_W (TypeNode *node,
|
|||||||
data->instance.class_data = info->class_data;
|
data->instance.class_data = info->class_data;
|
||||||
data->instance.class = NULL;
|
data->instance.class = NULL;
|
||||||
data->instance.instance_size = info->instance_size;
|
data->instance.instance_size = info->instance_size;
|
||||||
|
if (NODE_PARENT_TYPE (node))
|
||||||
|
{
|
||||||
|
TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
|
||||||
|
data->instance.private_size = pnode->data->instance.private_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data->instance.private_size = 0;
|
||||||
#ifdef DISABLE_MEM_POOLS
|
#ifdef DISABLE_MEM_POOLS
|
||||||
data->instance.n_preallocs = 0;
|
data->instance.n_preallocs = 0;
|
||||||
#else /* !DISABLE_MEM_POOLS */
|
#else /* !DISABLE_MEM_POOLS */
|
||||||
@ -1338,6 +1362,19 @@ type_iface_blow_holder_info_Wm (TypeNode *iface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assumes type's class already exists
|
||||||
|
*/
|
||||||
|
static inline size_t
|
||||||
|
type_total_instance_size_I (TypeNode *node)
|
||||||
|
{
|
||||||
|
gsize total_instance_size;
|
||||||
|
|
||||||
|
total_instance_size = node->data->instance.instance_size;
|
||||||
|
if (node->data->instance.private_size != 0)
|
||||||
|
total_instance_size = ALIGN_STRUCT (total_instance_size) + node->data->instance.private_size;
|
||||||
|
|
||||||
|
return total_instance_size;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- type structure creation/destruction --- */
|
/* --- type structure creation/destruction --- */
|
||||||
GTypeInstance*
|
GTypeInstance*
|
||||||
@ -1347,6 +1384,7 @@ g_type_create_instance (GType type)
|
|||||||
GTypeInstance *instance;
|
GTypeInstance *instance;
|
||||||
GTypeClass *class;
|
GTypeClass *class;
|
||||||
guint i;
|
guint i;
|
||||||
|
gsize total_instance_size;
|
||||||
|
|
||||||
node = lookup_type_node_I (type);
|
node = lookup_type_node_I (type);
|
||||||
if (!node || !node->is_instantiatable)
|
if (!node || !node->is_instantiatable)
|
||||||
@ -1364,21 +1402,35 @@ g_type_create_instance (GType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
class = g_type_class_ref (type);
|
class = g_type_class_ref (type);
|
||||||
|
|
||||||
|
total_instance_size = type_total_instance_size_I (node);
|
||||||
|
|
||||||
if (node->data->instance.n_preallocs)
|
if (node->data->instance.n_preallocs)
|
||||||
{
|
{
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
G_WRITE_LOCK (&type_rw_lock);
|
||||||
if (!node->data->instance.mem_chunk)
|
if (!node->data->instance.mem_chunk)
|
||||||
node->data->instance.mem_chunk = g_mem_chunk_new (NODE_NAME (node),
|
{
|
||||||
node->data->instance.instance_size,
|
/* If there isn't private data, the compiler will have already
|
||||||
(node->data->instance.instance_size *
|
* added the necessary padding, but in the private data case, we
|
||||||
node->data->instance.n_preallocs),
|
* have to pad ourselves to ensure proper alignment of all the
|
||||||
G_ALLOC_AND_FREE);
|
* atoms in the slab.
|
||||||
|
*/
|
||||||
|
gsize atom_size = total_instance_size;
|
||||||
|
if (node->data->instance.private_size)
|
||||||
|
atom_size = ALIGN_STRUCT (atom_size);
|
||||||
|
|
||||||
|
node->data->instance.mem_chunk = g_mem_chunk_new (NODE_NAME (node),
|
||||||
|
atom_size,
|
||||||
|
(atom_size *
|
||||||
|
node->data->instance.n_preallocs),
|
||||||
|
G_ALLOC_AND_FREE);
|
||||||
|
}
|
||||||
|
|
||||||
instance = g_chunk_new0 (GTypeInstance, node->data->instance.mem_chunk);
|
instance = g_chunk_new0 (GTypeInstance, node->data->instance.mem_chunk);
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
G_WRITE_UNLOCK (&type_rw_lock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
instance = g_malloc0 (node->data->instance.instance_size); /* fine without read lock */
|
instance = g_malloc0 (total_instance_size); /* fine without read lock */
|
||||||
for (i = node->n_supers; i > 0; i--)
|
for (i = node->n_supers; i > 0; i--)
|
||||||
{
|
{
|
||||||
TypeNode *pnode;
|
TypeNode *pnode;
|
||||||
@ -1424,7 +1476,7 @@ g_type_free_instance (GTypeInstance *instance)
|
|||||||
|
|
||||||
instance->g_class = NULL;
|
instance->g_class = NULL;
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
memset (instance, 0xaa, node->data->instance.instance_size); /* debugging hack */
|
memset (instance, 0xaa, type_total_instance_size_I (node)); /* debugging hack */
|
||||||
#endif
|
#endif
|
||||||
if (node->data->instance.n_preallocs)
|
if (node->data->instance.n_preallocs)
|
||||||
{
|
{
|
||||||
@ -1527,7 +1579,7 @@ type_class_init_Wm (TypeNode *node,
|
|||||||
g_assert (node->is_classed && node->data &&
|
g_assert (node->is_classed && node->data &&
|
||||||
node->data->class.class_size &&
|
node->data->class.class_size &&
|
||||||
!node->data->class.class);
|
!node->data->class.class);
|
||||||
|
|
||||||
class = g_malloc0 (node->data->class.class_size);
|
class = g_malloc0 (node->data->class.class_size);
|
||||||
node->data->class.class = class;
|
node->data->class.class = class;
|
||||||
|
|
||||||
@ -2255,8 +2307,7 @@ type_node_check_conformities_UorL (TypeNode *node,
|
|||||||
gboolean match;
|
gboolean match;
|
||||||
|
|
||||||
if (/* support_inheritance && */
|
if (/* support_inheritance && */
|
||||||
iface_node->n_supers <= node->n_supers &&
|
NODE_IS_ANCESTOR (iface_node, node))
|
||||||
node->supers[node->n_supers - iface_node->n_supers] == NODE_TYPE (iface_node))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
support_interfaces = support_interfaces && node->is_instantiatable && NODE_IS_IFACE (iface_node);
|
support_interfaces = support_interfaces && node->is_instantiatable && NODE_IS_IFACE (iface_node);
|
||||||
@ -3025,3 +3076,83 @@ g_type_init (void)
|
|||||||
{
|
{
|
||||||
g_type_init_with_debug_flags (0);
|
g_type_init_with_debug_flags (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_type_class_add_private (gpointer g_class,
|
||||||
|
gsize private_size)
|
||||||
|
{
|
||||||
|
GType instance_type = ((GTypeClass *)g_class)->g_type;
|
||||||
|
TypeNode *node = lookup_type_node_I (instance_type);
|
||||||
|
gsize offset;
|
||||||
|
|
||||||
|
if (!node || !node->is_instantiatable || !node->data || node->data->class.class != g_class)
|
||||||
|
{
|
||||||
|
g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'",
|
||||||
|
type_descriptive_name_I (instance_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NODE_PARENT_TYPE (node))
|
||||||
|
{
|
||||||
|
TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
|
||||||
|
if (node->data->instance.private_size != pnode->data->instance.private_size)
|
||||||
|
{
|
||||||
|
g_warning ("g_type_add_private() called multiple times for the same type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
G_WRITE_LOCK (&type_rw_lock);
|
||||||
|
|
||||||
|
offset = ALIGN_STRUCT (node->data->instance.private_size);
|
||||||
|
node->data->instance.private_size = offset + private_size;
|
||||||
|
|
||||||
|
G_WRITE_UNLOCK (&type_rw_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpointer
|
||||||
|
g_type_instance_get_private (GTypeInstance *instance,
|
||||||
|
GType private_type)
|
||||||
|
{
|
||||||
|
TypeNode *instance_node;
|
||||||
|
TypeNode *private_node;
|
||||||
|
TypeNode *parent_node;
|
||||||
|
gsize offset;
|
||||||
|
|
||||||
|
g_return_val_if_fail (instance != NULL && instance->g_class != NULL, NULL);
|
||||||
|
|
||||||
|
instance_node = lookup_type_node_I (instance->g_class->g_type);
|
||||||
|
if (G_UNLIKELY (!instance_node || !instance_node->is_instantiatable))
|
||||||
|
{
|
||||||
|
g_warning ("instance of invalid non-instantiatable type `%s'",
|
||||||
|
type_descriptive_name_I (instance->g_class->g_type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private_node = lookup_type_node_I (private_type);
|
||||||
|
if (G_UNLIKELY (!private_node || !NODE_IS_ANCESTOR (private_node, instance_node)))
|
||||||
|
{
|
||||||
|
g_warning ("attempt to retrieve private data for invalid type '%s'",
|
||||||
|
type_descriptive_name_I (private_type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that we don't need a read lock, since instance existing
|
||||||
|
* means that the instance class and all parent classes
|
||||||
|
* exist, so the node->data, node->data->instance.instance_size,
|
||||||
|
* and node->data->instance.private_size are not going to be changed.
|
||||||
|
* for any of the relevant types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
offset = ALIGN_STRUCT (instance_node->data->instance.instance_size);
|
||||||
|
|
||||||
|
if (NODE_PARENT_TYPE (private_node))
|
||||||
|
{
|
||||||
|
parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
|
||||||
|
g_assert (parent_node->data && parent_node->data->common.ref_count);
|
||||||
|
|
||||||
|
offset += ALIGN_STRUCT (parent_node->data->instance.private_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return G_STRUCT_MEMBER_P (instance, offset);
|
||||||
|
}
|
||||||
|
@ -150,6 +150,8 @@ struct _GTypeQuery
|
|||||||
#define G_TYPE_FROM_CLASS(g_class) (((GTypeClass*) (g_class))->g_type)
|
#define G_TYPE_FROM_CLASS(g_class) (((GTypeClass*) (g_class))->g_type)
|
||||||
#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type)
|
#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type)
|
||||||
|
|
||||||
|
#define G_TYPE_INSTANCE_GET_PRIVATE(instance, g_type, c_type) ((c_type*) g_type_instance_get_private ((GTypeInstance*) (instance), (g_type)))
|
||||||
|
|
||||||
|
|
||||||
/* debug flags for g_type_init_with_debug_flags() */
|
/* debug flags for g_type_init_with_debug_flags() */
|
||||||
typedef enum /*< skip >*/
|
typedef enum /*< skip >*/
|
||||||
@ -298,6 +300,10 @@ void g_type_interface_add_prerequisite (GType interface_type,
|
|||||||
GType *g_type_interface_prerequisites (GType interface_type,
|
GType *g_type_interface_prerequisites (GType interface_type,
|
||||||
guint *n_prerequisites);
|
guint *n_prerequisites);
|
||||||
|
|
||||||
|
void g_type_class_add_private (gpointer g_class,
|
||||||
|
gsize private_size);
|
||||||
|
gpointer g_type_instance_get_private (GTypeInstance *instance,
|
||||||
|
GType private_type);
|
||||||
|
|
||||||
/* --- protected (for fundamental type implementations) --- */
|
/* --- protected (for fundamental type implementations) --- */
|
||||||
GTypePlugin* g_type_get_plugin (GType type);
|
GTypePlugin* g_type_get_plugin (GType type);
|
||||||
|
@ -126,8 +126,10 @@ iface_print_string (TestIface *tiobj,
|
|||||||
#define TEST_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
|
#define TEST_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
|
||||||
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||||
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||||
typedef struct _TestObject TestObject;
|
#define TEST_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TEST_TYPE_OBJECT, TestObjectPrivate))
|
||||||
typedef struct _TestObjectClass TestObjectClass;
|
typedef struct _TestObject TestObject;
|
||||||
|
typedef struct _TestObjectClass TestObjectClass;
|
||||||
|
typedef struct _TestObjectPrivate TestObjectPrivate;
|
||||||
struct _TestObject
|
struct _TestObject
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -140,6 +142,11 @@ struct _TestObjectClass
|
|||||||
TestIface *iface_object,
|
TestIface *iface_object,
|
||||||
gpointer tdata);
|
gpointer tdata);
|
||||||
};
|
};
|
||||||
|
struct _TestObjectPrivate
|
||||||
|
{
|
||||||
|
int dummy1;
|
||||||
|
gdouble dummy2;
|
||||||
|
};
|
||||||
static void test_object_class_init (TestObjectClass *class);
|
static void test_object_class_init (TestObjectClass *class);
|
||||||
static void test_object_init (TestObject *tobject);
|
static void test_object_init (TestObject *tobject);
|
||||||
static gboolean test_signal_accumulator (GSignalInvocationHint *ihint,
|
static gboolean test_signal_accumulator (GSignalInvocationHint *ihint,
|
||||||
@ -190,10 +197,18 @@ test_object_class_init (TestObjectClass *class)
|
|||||||
test_signal_accumulator, NULL,
|
test_signal_accumulator, NULL,
|
||||||
g_cclosure_marshal_STRING__OBJECT_POINTER,
|
g_cclosure_marshal_STRING__OBJECT_POINTER,
|
||||||
G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
|
G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
|
||||||
|
|
||||||
|
g_type_class_add_private (class, sizeof (TestObjectPrivate));
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
test_object_init (TestObject *tobject)
|
test_object_init (TestObject *tobject)
|
||||||
{
|
{
|
||||||
|
TestObjectPrivate *priv;
|
||||||
|
|
||||||
|
priv = TEST_OBJECT_GET_PRIVATE (tobject);
|
||||||
|
|
||||||
|
g_assert (priv);
|
||||||
|
g_assert ((gchar *)priv >= (gchar *)tobject + sizeof (TestObject));
|
||||||
}
|
}
|
||||||
static gboolean
|
static gboolean
|
||||||
test_signal_accumulator (GSignalInvocationHint *ihint,
|
test_signal_accumulator (GSignalInvocationHint *ihint,
|
||||||
@ -274,8 +289,16 @@ derived_object_test_iface_init (gpointer giface,
|
|||||||
#define DERIVED_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), DERIVED_TYPE_OBJECT))
|
#define DERIVED_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), DERIVED_TYPE_OBJECT))
|
||||||
#define DERIVED_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DERIVED_TYPE_OBJECT))
|
#define DERIVED_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DERIVED_TYPE_OBJECT))
|
||||||
#define DERIVED_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DERIVED_TYPE_OBJECT, DerivedObjectClass))
|
#define DERIVED_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DERIVED_TYPE_OBJECT, DerivedObjectClass))
|
||||||
typedef struct _TestObject DerivedObject;
|
#define DERIVED_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DERIVED_TYPE_OBJECT, DerivedObjectPrivate))
|
||||||
typedef struct _TestObjectClass DerivedObjectClass;
|
typedef struct _TestObject DerivedObject;
|
||||||
|
typedef struct _TestObjectClass DerivedObjectClass;
|
||||||
|
typedef struct _DerivedObjectPrivate DerivedObjectPrivate;
|
||||||
|
struct _DerivedObjectPrivate
|
||||||
|
{
|
||||||
|
char dummy;
|
||||||
|
};
|
||||||
|
static void derived_object_class_init (DerivedObjectClass *class);
|
||||||
|
static void derived_object_init (DerivedObject *dobject);
|
||||||
GType
|
GType
|
||||||
derived_object_get_type (void)
|
derived_object_get_type (void)
|
||||||
{
|
{
|
||||||
@ -288,12 +311,12 @@ derived_object_get_type (void)
|
|||||||
sizeof (DerivedObjectClass),
|
sizeof (DerivedObjectClass),
|
||||||
NULL, /* base_init */
|
NULL, /* base_init */
|
||||||
NULL, /* base_finalize */
|
NULL, /* base_finalize */
|
||||||
NULL, /* class_init */
|
(GClassInitFunc) derived_object_class_init,
|
||||||
NULL, /* class_finalize */
|
NULL, /* class_finalize */
|
||||||
NULL, /* class_data */
|
NULL, /* class_data */
|
||||||
sizeof (DerivedObject),
|
sizeof (DerivedObject),
|
||||||
5, /* n_preallocs */
|
5, /* n_preallocs */
|
||||||
NULL, /* instance_init */
|
(GInstanceInitFunc) derived_object_init,
|
||||||
};
|
};
|
||||||
GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) };
|
GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) };
|
||||||
|
|
||||||
@ -303,7 +326,28 @@ derived_object_get_type (void)
|
|||||||
|
|
||||||
return derived_object_type;
|
return derived_object_type;
|
||||||
}
|
}
|
||||||
|
static void
|
||||||
|
derived_object_class_init (DerivedObjectClass *class)
|
||||||
|
{
|
||||||
|
g_type_class_add_private (class, sizeof (DerivedObjectPrivate));
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
derived_object_init (DerivedObject *dobject)
|
||||||
|
{
|
||||||
|
TestObjectPrivate *test_priv;
|
||||||
|
DerivedObjectPrivate *derived_priv;
|
||||||
|
|
||||||
|
derived_priv = DERIVED_OBJECT_GET_PRIVATE (dobject);
|
||||||
|
|
||||||
|
g_assert (derived_priv);
|
||||||
|
g_assert ((gchar *)derived_priv >= (gchar *)TEST_OBJECT_GET_PRIVATE (dobject) + sizeof (TestObjectPrivate));
|
||||||
|
|
||||||
|
test_priv = TEST_OBJECT_GET_PRIVATE (dobject);
|
||||||
|
|
||||||
|
g_assert (test_priv);
|
||||||
|
g_assert ((gchar *)test_priv >= (gchar *)dobject + sizeof (TestObject));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* --- main --- */
|
/* --- main --- */
|
||||||
int
|
int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user