gpt4 book ai didi

gtk - GValue、GTypeValueTable、GTypeInfo 和 GParamSpec 的用途

转载 作者:行者123 更新时间:2023-12-04 10:01:07 25 4
gpt4 key购买 nike

GObject 库的文档非常详细。很难弄清楚创建实体的目的。即,我没有得到 GValue 的角色, GTypeValueTable , GTypeInfo , GParamSpecTypeData .

简而言之,类型注册的过程如下。每种类型由 TypeNode 表示结构体。 TypeNode有2个存储结构:static_fundamental_type_nodes array用于存储 TypeNodes静态基本类型和static_type_nodes_ht静态非基本类型的哈希表。每个GType就是对应TypeNode的内存地址如果是 TypeNode 的非基本类型或索引在 static_fundamental_type_nodes在基本类型的情况下。动态类型会发生什么 - 我不知道,如果可以请解释一下。对应的代码驻留在gtype_init函数中,负责类型系统的初始化:http://git.gnome.org/browse/glib/tree/gobject/gtype.c#n4323 .

enter image description here
GValue , GParamSpecGObjectGTypes他们自己,所以他们被注册为类型。
GValue意味着用于通过它注册新的类型值,但是如何呢?
GParametersGParamSpec似乎需要注册GObject类型(不确定)。它究竟是如何完成的?各自的作用是什么?

最重要的是:GTypeValueTable 的角色是什么? , GTypeInfoTypeData ? TypeDataTypeNode 引用并包含 GTypeValueTable以及子结构 BoxedData、ClassData、IFaceData、InstanceData(为什么是 Instance,我们不是在注册类型吗?)。此外,它们似乎相互重复,因为它们都包含对 base_init/finalize 的引用,class_init/finalize 对 GTypeValueTable 的引用.

所以,GObject 爸爸,如果你正在阅读这篇文章,请解释一下自己!描述你使用的那些结构的目的。

最佳答案

除非您尝试处理一些非常低级的代码,否则您真正需要关心的仅有两个是 GValue 和 GParamType

我将从 GParamType 开始
GParamType用于向 GObject 注册属性。比如说,我有一个名为 Person 的 GObject 子类,我希望它有两个属性:Name 和 Age。在 class_init功能我会像这样注册这些

{
GParamSpec *pspec;

. . .

pspec = g_param_spec_string ("name", "Name", "The name of the person", "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_NAME, pspec);

pspec = g_param_spec_int ("age", "Age", "The age of the person", 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_AGE, spec);

. . .
}

现在您可以调用 g_object_getg_object_set在这些属性上,系统将知道如何处理它
char *name;
int age;
g_object_set (G_OBJECT (person), "name", "Steve", "age", 37, NULL);
g_object_get (G_OBJECT (person), "name", &name, "age", &age, NULL);

g_print ("%s is %d years old\n", name, age);

// And because the type system knows when a property is a string, it knows how to give
// you a copy of the string, so you need to free it once you've finished with it
g_free (name);

这里解释了各种参数: GParamSpec所有标准类型都有 GValue 类型:字符串、 bool 值、整数等,而 GStreamer 等其他一些库将注册自己的自定义类型。

除了在 GObjectClass 上安装属性之外,您很少需要处理 GParamSpec。它们出现的两个主要场合是在 GObjectClass 的 set/get_property 方法和 GObject 通知信号中。在最后一种情况下,通过调用 g_param_spec_get_name 来检测哪个属性收到了通知信号很有用。 ,但实际上最好使用更具体的通知信号,如下所示:
g_signal_connect (person, "notify::name", G_CALLBACK (name_changed_cb), NULL);
g_signal_connect (person, "notify::age", G_CALLBACK (age_changed_cb), NULL);

而不是
g_signal_connect (person, "notify", G_CALLBACK (something_changed_cb), NULL);

有时您可能想要创建自己的结构并将其用于属性。例如,如果我有
struct _PersonDetails {
char *name;
int age;
}

而不是在 Person 对象上有两个属性,我想要一个称为“详细信息”的属性。 GLib类型系统不知道怎么处理我自定义的 struct _PersonDetails所以我需要为它创建一个盒装类型,以便它知道如何正确复制/释放结构,因为它在 Glib 内部传递。这就是 GValue进来。
GValue用于包装不同类型的值,以便可以正确复制和释放它们(如果需要),并且可以使用通用函数。

例如,GObjectClass 方法 set_property 的原型(prototype)为
void set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)

这意味着可以传入任何可以由 GValue 表示的类型,并且不需要特定的函数,例如 set_int_property、set_string_property、set_bool_property。

这也意味着函数 g_object_setg_object_get知道如何处理传入的参数,因为它知道属性“name”已注册为字符串类型,并且它具有复制/释放该字符串所需的功能。

更多关于 GValue 的信息可以在这里找到 - Generic values

注册我们的定制 struct _PersonDetails使用 GLib 类型系统,我们将创建一个自定义的 Boxed 类型,它告诉系统如何复制和释放它。详情在这里: Boxed Types
G_DEFINE_BOXED_TYPE (PersonDetails, person_details,
person_details_copy,
person_details_free)
. . .

static gpointer
person_details_copy (gpointer data)
{
struct _PersonDetails *details = (struct _PersonDetails *)data;
struct _PersonDetails *copy = g_new (struct _PersonDetails, 1);

// We need to copy the string
copy->name = g_strdup (details->name);
copy->age = details->age;

return (gpointer) copy;
}

static void
person_details_free (gpointer data)
{
struct _PersonDetails *details = (struct _PersonDetails *)data;

// name was allocated so it needs freed as well
g_free (details->name);

g_free (details);
}

现在我们可以使用注册我们的类型
pspec = g_param_spec_boxed ("details", "Details", "The person's details", person_details_get_type (), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DETAILS, pspec);

关于gtk - GValue、GTypeValueTable、GTypeInfo 和 GParamSpec 的用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14840456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com