GObject – 2.0: Generic Value Container
Description: Reference for GObject-2.0: Generic Value Container

#### Generic Value Container

The `GValue` 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 `g_value_init()` function. A `GValue` cannot be used until it is initialized.

Once you have finished using a `GValue`, you must call `g_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 `GTypeValueTable` 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);
    }