I'm converting some C code from using GVariant
to GValue
as it seems to fit what I'm doing with it better. With GVariant
, I could easily instantiate them using one of the many constructors listed in the documentation, e.g. g_variant_new_string ()
, but in the GValue documentation I don't see any constructors listed.
I tried doing something like this:
/* Instantiate the GValue structure. */
GValue *value = g_new (GValue, 1);
/* Initialise it to a string. */
g_value_init (value, G_TYPE_STRING);
/* Set it to some data. */
g_value_take_string (value, data);
However, this fails on g_value_init (value, G_TYPE_STRING)
with the following:
GLib-GObject-CRITICAL **: 17:29:30.782: ../gobject/gvalue.c:99: cannot initialize GValue with type 'gchararray', the value has already been initialized as '(null)'
I never intentionally initialised it to "(null)
", so clearly I'm doing something wrong.
I also tried using GValue *value = malloc (sizeof (GValue))
, but this results in a segmentation fault when I use it in g_value_init ()
.
Another thing I tried was GValue *value = g_object_new (G_TYPE_VALUE, NULL)
, but this fails with the following:
GLib-GObject-CRITICAL **: 17:49:23.518: g_object_new_with_properties: assertion 'G_TYPE_IS_OBJECT (object_type)' failed
How do I properly instantiate a GValue
in C?
It turns out the answer is very simple: GValue
must be zero-filled in order to be initialised using g_value_init ()
. The easiest way to achieve this is to use g_new0 ()
instead of g_new ()
. So, to fix the above example, something like this would work:
/* Instantiate the GValue structure. */
GValue *value = g_new0 (GValue, 1);
/* Initialise it to a string. */
g_value_init (value, G_TYPE_STRING);
/* Set it to some data. */
g_value_take_string (value, data);
The only difference is that it's using g_new0 ()
instead of g_new ()
.