| Title: Generic Value Container | |
| # 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: | |
| ```c | |
| #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](boxed.html). The example below shows how | |
| the pointer `mystruct` of type `MyStruct` is used as a [boxed type](boxed.html). | |
| ```c | |
| 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); | |
| } | |
| ``` |