Title: Generic Value Container
The [struct@GObject.Value] structure is basically a variable container that consists of a type identifier and a specific value of that type. The type identifier within a GValue structure always determines the type of the associated value.
To create an undefined GValue structure, simply create a zero-filled GValue structure. To initialize the GValue, use the [method@GObject.Value.init] function. A GValue cannot be used until it is initialized.
Once you have finished using a GValue, you must call [method@GObject.Value.unset] to ensure that all the resources associated with the GValue are freed.
The basic type operations (such as freeing and copying) are determined by the [struct@GObject.TypeValueTable] associated with the type ID stored in the GValue. Other GValue operations (such as converting values between types) are provided by this interface.
The code in the example program below demonstrates GValue's features:
#include <glib-object.h> static void int2string (const GValue *src_value, GValue *dest_value) { if (g_value_get_int (src_value) == 42) g_value_set_static_string (dest_value, "An important number"); else g_value_set_static_string (dest_value, "What's that?"); } int main (int argc, char *argv[]) { // GValues must be initialized GValue a = G_VALUE_INIT; GValue b = G_VALUE_INIT; const char *message; // The GValue starts empty g_assert (!G_VALUE_HOLDS_STRING (&a)); // Put a string in it g_value_init (&a, G_TYPE_STRING); g_assert (G_VALUE_HOLDS_STRING (&a)); g_value_set_static_string (&a, "Hello, world!"); g_printf ("%s\n", g_value_get_string (&a)); // Reset it to its pristine state g_value_unset (&a); // It can then be reused for another type g_value_init (&a, G_TYPE_INT); g_value_set_int (&a, 42); // Attempt to transform it into a GValue of type STRING g_value_init (&b, G_TYPE_STRING); // An INT is transformable to a STRING g_assert (g_value_type_transformable (G_TYPE_INT, G_TYPE_STRING)); g_value_transform (&a, &b); g_printf ("%s\n", g_value_get_string (&b)); // Attempt to transform it again using a custom transform function g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, int2string); g_value_transform (&a, &b); g_printf ("%s\n", g_value_get_string (&b)); g_value_unset (&b); g_value_unset (&a); return 0; }
For letting a GValue own (and memory manage) arbitrary types or pointers, they need to become a boxed type. The example below shows how the pointer mystruct of type MyStruct is used as a boxed type.
typedef struct { ... } MyStruct; G_DEFINE_BOXED_TYPE (MyStruct, my_struct, my_struct_copy, my_struct_free) // These two lines normally go in a public header. By GObject convention, // the naming scheme is NAMESPACE_TYPE_NAME: #define MY_TYPE_STRUCT (my_struct_get_type ()) GType my_struct_get_type (void); void foo (void) { GValue *value = g_new0 (GValue, 1); g_value_init (value, MY_TYPE_STRUCT); g_value_set_boxed (value, mystruct); // [... your code ....] g_value_unset (value); g_free (value); }