带框类型
带框类型
“带框类型”是用于任意 C 结构的通用包装机制。类型系统需要了解的有关结构的唯一信息是如何复制它们(GBoxedCopyFunc
)以及如何释放它们(GBoxedFreeFunc
)—除此之外,它们被视为内存中的不透明块。
带框类型对于矩形或点等简单的值保持器结构很有用。它们还可用于包装基于非 GObject 库中定义的结构。它们允许以统一的方式处理任意结构,允许统一复制(或引用)和释放(或取消引用)它们,以及统一表示所包含结构的类型。反过来,这允许将任何可以框定的类型设置为 GValue
中的数据,从而可以对更广泛的数据类型进行多态处理,因此可以将这些类型用作 GObject
属性值。
所有带框类型都继承自 G_TYPE_BOXED
基本类型。
请务必注意,带框类型不可深继承:您不能注册从其他带框类型继承的带框类型。这意味着您不能创建自己自定义的并行类型层次结构,并使用带框类型将其映射到 GType。如果您想在不用 GObject 的情况下拥有深度可继承的类型,则需要使用 GTypeInstance
。
注册新的带框类型
注册新的带框类型的推荐方法是使用 G_DEFINE_BOXED_TYPE()
宏
// In the header
#define EXAMPLE_TYPE_RECTANGLE (example_rectangle_get_type())
typedef struct {
double x, y;
double width, height;
} ExampleRectangle;
GType
example_rectangle_get_type (void);
ExampleRectangle *
example_rectangle_copy (ExampleRectangle *r);
void
example_rectangle_free (ExampleRectangle *r);
// In the source
G_DEFINE_BOXED_TYPE (ExampleRectangle, example_rectangle,
example_rectangle_copy,
example_rectangle_free)
与 G_DEFINE_TYPE
和 G_DEFINE_INTERFACE_TYPE
一样,G_DEFINE_BOXED_TYPE
宏将提供 get_type()
函数的定义,它将以给定的类型名称以及 GBoxedCopyFunc
和 GBoxedFreeFunc
函数调用 g_boxed_type_register_static()
。
使用带框类型
对象属性
为了对 GObject 属性使用带框类型,您需要使用 g_param_spec_boxed()
注册属性,例如
obj_props[PROP_BOUNDS] =
g_param_spec_boxed ("bounds", NULL, NULL,
EXAMPLE_TYPE_RECTANGLE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
在 set_property
实现中,您可以使用 g_value_get_boxed()
检索带框类型的指针
switch (prop_id)
{
// ...
case PROP_BOUNDS:
example_object_set_bounds (self, g_value_get_boxed (value));
break;
// ...
}
类似地,您可以在 get_property
虚拟函数的实现中使用 g_value_set_boxed()
。
switch (prop_id)
{
// ...
case PROP_BOUNDS:
g_value_set_boxed (self, &self->bounds);
break;
// ...
}
引用计数
带框类型旨在使引用计数类型可以框定。将类型”的ref”函数用作 GBoxedCopyFunc
,并将它的”unref”函数用作 GBoxedFreeFunc
。例如,对于 GBytes
,GBoxedCopyFunc
是 g_bytes_ref()
,而 GBoxedFreeFunc 是 g_bytes_unref()
。