GObject instance is created with g_object_new
function.
GObject has not only instances but also classes.
g_object_new
. And there exists only one GObject class.g_object_new
is
called. So, two or more GObject instances can exist.In a broad sense, GObject means the object which includes its class and instances. In a narrow sense, GObject is a definition of a C structure.
typedef struct _GObject GObject;
struct _GObject
{
;
GTypeInstance g_type_instance
/*< private >*/
; /* (atomic) */
guint ref_count*qdata;
GData };
The g_object_new
function allocates GObject-sized
memory, initializes the memory and returns the pointer to the memory.
The memory is a GObject instance.
In the same way, the class of GObject is memory allocated by
g_object_new
and its structure is defined with
GObjectClass. The following is extracted from gobject.h
.
But you don’t need to know the details of the structure now.
struct _GObjectClass
{
;
GTypeClass g_type_class
/*< private >*/
*construct_properties;
GSList
/*< public >*/
/* seldom overridden */
* (*constructor) (GType type,
GObject,
guint n_construct_properties*construct_properties);
GObjectConstructParam /* overridable methods */
void (*set_property) (GObject *object,
,
guint property_idconst GValue *value,
*pspec);
GParamSpec void (*get_property) (GObject *object,
,
guint property_id*value,
GValue *pspec);
GParamSpec void (*dispose) (GObject *object);
void (*finalize) (GObject *object);
/* seldom overridden */
void (*dispatch_properties_changed) (GObject *object,
,
guint n_pspecs**pspecs);
GParamSpec /* signals */
void (*notify) (GObject *object,
*pspec);
GParamSpec
/* called when done constructing */
void (*constructed) (GObject *object);
/*< private >*/
;
gsize flags
;
gsize n_construct_properties
;
gpointer pspecs;
gsize n_pspecs
/* padding */
[3];
gpointer pdummy};
The programs for GObject are included in GLib source files. You can download the GLib source files from GNOME download page.
There are sample programs in src/misc directory in the GObject tutorial repository. You can compile them by:
$ cd src/misc
$ meson setup _build
$ ninja -C _build
One of the programs is example1.c
. Its code is as
follows.
#include <glib-object.h>
int
main (int argc, char **argv) {
GObject *instance1, *instance2;
GObjectClass *class1, *class2;
instance1 = g_object_new (G_TYPE_OBJECT, NULL);
instance2 = g_object_new (G_TYPE_OBJECT, NULL);
g_print ("The address of instance1 is %p\n", instance1);
g_print ("The address of instance2 is %p\n", instance2);
class1 = G_OBJECT_GET_CLASS (instance1);
class2 = G_OBJECT_GET_CLASS (instance2);
g_print ("The address of the class of instance1 is %p\n", class1);
g_print ("The address of the class of instance2 is %p\n", class2);
g_object_unref (instance1);
g_object_unref (instance2);
return 0;
}
instance1
and instance2
are pointers
that points GObject instances. class1
and
class2
points a class of the instances.g_object_new
creates a GObject
instance. GObject instance is a chunk of memory which has GObject
structure (struct _GObject
). The argument
G_TYPE_OBJECT
is the type of GObject. This type is
different from C language type like char
or
int
. There is Type System which is a base system
of GObject system. Every data type such as GObject must be registered to
the type system. The type system has series of functions for the
registration. If one of the functions is called, then the type system
determines GType
type value for the object and returns it
to the caller. GType
is an unsigned long integer on my
computer but it depends on the hardware. g_object_new
allocates GObject-sized memory and returns the pointer to the top
address of the memory. After the creation, this program displays the
addresses of instances.G_OBJECT_GET_CLASS
returns the pointer
to the class of the argument. Therefore, class1
points the
class of instance1
and class2
points the class
of instance2
respectively. The addresses of the two classes
are displayed.g_object_unref
will be explained in the next
subsection. It destroys the instances and the memory is freed.Now, execute it.
$ cd src/misc; _build/example1
The address of instance1 is 0x55895eaf7ad0
The address of instance2 is 0x55895eaf7af0
The address of the class of instance1 is 0x55895eaf7880
The address of the class of instance2 is 0x55895eaf7880
The locations of two instances instance1
and
instance2
are different. Each instance has its own memory.
The locations of two classes class1
and class2
are the same. Two GObject instances share the same class.
GObject instance has its own memory. They are allocated by the system when it is created. If it becomes useless, the memory must be freed. However, how can we determine whether it is useless? GObject system provides reference count to solve the problem.
An instance is created and used by other instance or the main program. That is to say, the instance is referred. If the instance is referred by A and B, then the number of the reference is two. This number is called reference count. Let’s think about a scenario like this:
g_object_new
and owns an instance G. A refers
G, so the reference count of G is 1.g_object_ref
and
increases the reference count by 1. Now the reference count is 2.g_object_unref
and
decreases the reference count by 1. Now the reference count is 1.g_object_unref
and
decreases the reference count by 1. Now the reference count is 0.A program example2.c
is based on the scenario above.
#include <glib-object.h>
static void
show_ref_count (GObject *instance) {
if (G_IS_OBJECT (instance))
/* Users should not use ref_count member in their program. */
/* This is only for demonstration. */
g_print ("Reference count is %d.\n", instance->ref_count);
else
g_print ("Instance is not GObject.\n");
}
int
main (int argc, char **argv) {
GObject *instance;
instance = g_object_new (G_TYPE_OBJECT, NULL);
g_print ("Call g_object_new.\n");
show_ref_count (instance);
g_object_ref (instance);
g_print ("Call g_object_ref.\n");
show_ref_count (instance);
g_object_unref (instance);
g_print ("Call g_object_unref.\n");
show_ref_count (instance);
g_object_unref (instance);
g_print ("Call g_object_unref.\n");
g_print ("Now the reference count is zero and the instance is destroyed.\n");
g_print ("The instance memories are possibly returned to the system.\n");
g_print ("Therefore, the access to the same address may cause a segmentation error.\n");
return 0;
}
Now execute it.
$ cd src/misc; _build/example2
bash: cd: src/misc: No such file or directory
Call g_object_new.
Reference count is 1.
Call g_object_ref.
Reference count is 2.
Call g_object_unref.
Reference count is 1.
Call g_object_unref.
Now the reference count is zero and the instance is destroyed.
The instance memories are possibly returned to the system.
Therefore, the access to the same address may cause a segmentation error.
example2
shows:
g_object_new
creates a new GObject instance and sets
its reference count to 1.g_object_ref
increases the reference count by 1.g_object_unref
decreases the reference count by 1. If
the reference count drops to zero, the instance destroys itself.The actual process of GObject initialization and destruction is very complex. The following is simplified description without details.
Initialization
main
is
called. (If the compiler is gcc, then
__attribute__ ((constructor))
is used to qualify the
initialization function. Refer to GCC
manual.)This initialization process is carried out when
g_object_new
function is called for the first time. At the
second and subsequent call for g_object_new
, it performs
only two processes: (1) memory allocation for GObject structure (2)
initialization for the memory. g_object_new
returns the
pointer that points the instance (the memory allocated for the GObject
structure).
Destruction
GObject type is a static type. Static type never destroys its class. So, even if the destroyed instance is the last instance, the class still remains.
When you write code to define a child object of GObject, It is important to understand the process above. The detailed process will be explained in the later sections.