带框类型

带框类型

“带框类型”是用于任意 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_TYPEG_DEFINE_INTERFACE_TYPE 一样,G_DEFINE_BOXED_TYPE 宏将提供 get_type() 函数的定义,它将以给定的类型名称以及 GBoxedCopyFuncGBoxedFreeFunc 函数调用 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。例如,对于 GBytesGBoxedCopyFuncg_bytes_ref(),而 GBoxedFreeFunc 是 g_bytes_unref()