带框类型
带框类型
“带框类型”是用于任意 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()。