Coding Guidelines/GValue Handling
The Glib documentation on GValues is a bit verbose, and requires you to understand the Glib type system fairly well. If all you need are some recipes, this should help.
Pieces
Setup
GValues are usually allocated on the stack or in a struct. They must be zero-filled.
GValue val = {0, };
You now have an uninitialized (empty, typeless) GValue. You can also use memset to clear the value:
memset(&val, 0, sizeof(val));
Set a GValue
To go from the unitialized state to something containing a value, first set the type, then set the value
g_value_init(&val, G_TYPE_UINT); g_value_set_uint(&val, myuintvalue);
Clear a GValue
A GValue object may contain a pointer to allocated memory, or require some other cleanup. When you're done with it:
g_value_unset(&val)
This puts the GValue back to the uninitialized state.
As a shortcut to changing the type of a GValue, you can use the Amanda utility function
g_value_unset_init(&val, G_TYPE_INT64);
which is equivalent to
g_value_unset(&val); g_value_init(&val, G_TYPE_INT64);
Copy a GValue
The Amanda utility function g_value_unset_copy helps to copy one GValue to another, overwriting any value in the target (which must be uninitialized or have a value).
GValue newcopy; memset(&newcopy, 0, sizeof(newcopy)); g_value_unset_copy(&input, &newcopy);
Common Uses
Setting a Device Property
GValue val; memset(&val, 0, sizeof(val));
g_value_init(&val, G_TYPE_UINT); g_value_set_uint(&val, blocksize); success = device_property_set(device, PROPERTY_BLOCK_SIZE, &val); g_value_unset(&val);
Getting a Device Property
GValue val; memset(&val, 0, sizeof(val)); if (device_property_get(taper_state->device, PROPERTY_STREAMING, &val) { || !G_VALUE_HOLDS(&val, STREAMING_REQUIREMENT_TYPE)) { g_fprintf(stderr, "taper: Couldn't get streaming type!\n"); streaming_mode = STREAMING_REQUIREMENT_REQUIRED; } else { streaming_mode = g_value_get_enum(&val); g_value_unset($val); }
note that you shouldn't call g_value_unset if the device_property_get call fails.