通用值容器
通用值容器
GValue
结构基本上是一个变量容器,它由一个类型标识符和该类型特定的值组成。在 GValue
结构内部,类型标识符始终确定相关值的数据类型。
要创建一个未定义的 GValue
结构,只需创建一个零填充的 GValue 结构。要初始化 GValue
,请使用 g_value_init()
函数。未初始化的 GValue
不能使用。
一旦使用完 GValue
,就必须调用 g_value_unset()
来确保释放与 GValue
相关的所有资源。
基本类型操作(如释放和复制)由存储在 GValue
中的类型 ID 关联的 GTypeValueTable
确定。其他 GValue
操作(如值之间的类型转换)由该界面提供。
以下示例程序中的代码演示了 GValue
的功能
#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;
}
为了让 GValue
拥有(并内存管理)任意类型或指针,它们需要成为一个boxed 类型。以下示例显示了如何将类型为 MyStruct
的指针 mystruct
作为boxed 类型使用。
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);
}