摘要:GObject是Glib库的一部分,提供了一个灵活的、可扩展的、并且容易映射到其他语言的面向对象的C语言框架。以下是GObject的一些核心概念和使用方法。
GObject是Glib库的一部分,提供了一个灵活的、可扩展的、并且容易映射到其他语言的面向对象的C语言框架。以下是GObject的一些核心概念和使用方法。
源码:https://gitlab.gnome.org/GNOME/glib/
教程:https://docs.gtk.org/gobject/index.html
在GObject中,类和实例是两个结构体的组合。类结构体初始化函数一般被调用一次,而实例结构体的初始化函数的调用次数等于对象实例化的次数。所有实例共享的数据保存在类结构体中,而对象私有的数据保存在实例结构体中。
GObject实例的结构体定义如下:
typedef struct _GObject GObject;struct _GObject{ GTypeInstance g_type_instance; /**/ guint ref_count; /* (atomic) */ GData *qdata;};GObject类的结构体定义如下:
struct _GObjectClass{ GTypeClass g_type_class; /**/ GSList *construct_properties; /**/ /* seldom overridden */ GObject* (*constructor) (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties); /* overridable methods */ void (*set_property) (GObject *object, guint property_id, const GValue *value, Gparamspec *pspec); void (*get_property) (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); void (*dispose) (GObject *object); void (*finalize) (GObject *object); /* seldom overridden */ void (*dispatch_properties_CHANGED) (GObject *object, guint n_pspecs, GParamSpec **pspecs); /* signals */ void (*notify) (GObject *object, GParamSpec *pspec); /* called when done constructing */ void (*constructed) (GObject *object); /**/ gsize flags; gsize n_construct_properties; gpointer pspecs; gsize n_pspecs; /* padding */ gpointer pdummy[3];};以下是一个简单的示例,展示了如何创建和使用GObject实例:
#include int main (int argc, char **argv) { GObject* instance1, *instance2; // 指向实例的指针 GObjectClass* class1, *class2; // 指向类的指针 instance1 = g_object_new (G_TYPE_OBJECT, NULL); instance2 = g_object_new (G_TYPE_OBJECT, NULL); g_print ("The address of instance1 is %p\n", instance1); g_print ("The address of instance2 is %p\n", instance2); class1 = G_OBJECT_GET_CLASS (instance1); class2 = G_OBJECT_GET_CLASS (instance2); g_print ("The address of the class of instance1 is %p\n", class1); g_print ("The address of the class of instance2 is %p\n", class2); g_object_unref (instance1); g_object_unref (instance2); return 0;}The address of instance1 is 0x55d3ddc05600The address of instance2 is 0x55d3ddc05620The address of the class of instance1 is 0x55d3ddc05370The address of the class of instance2 is 0x55d3ddc05370在这个示例中,g_object_new 函数用于创建GObject实例,并返回指向它的指针。G_TYPE_OBJECT 是GObject基类的类型标识符,所有其他GObject类型都从这个基类型派生。宏 G_OBJECT_GET_CLASS 返回指向参数所属类变量的指针。g_object_unref 用于销毁实例变量并释放内存。
实例1与实例2的存储空间是不同的,每个实例都有自己的空间。两个类的存储空间是相同的,两个GObject实例共享同一个类。
GObject允许定义和使用属性,以及发出和连接信号。这些特性使得GObject非常适合用于构建复杂的软件系统,尤其是在需要组件间通信和属性管理的场景中。
信号最基本的用途是实现事件通知。例如:创建一个信号,当调用文件写方法时,触发文件变化信号。
创建信号:
File_signals[CHANGED] = g_signal_newv ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, NULL /* closure */, NULL /* accumulator */, NULL /* accumulator data */, NULL /* C marshaller */, G_TYPE_NONE /* return_type */, 0 /* n_params */, NULL /* param_types */);带信号机制的文件写方法:
voidviewer_file_write (ViewerFile *self, const guint8 *buffer, gsize size){ g_return_if_fail (VIEWER_IS_FILE (self)); g_return_if_fail (buffer != NULL || size == 0); /* First write data. */ /* Then, notify user of data written. */ g_signal_emit (self, file_signals[CHANGED], 0 /* details */);}用户回调处理函数连接到信号:
g_signal_connect (file, "changed", (GCallback) changed_event, NULL);GObject被设计为可以直接使用在C程序中,并且可以封装至其他语言,如C++、Java、Ruby、Python和.NET/Mono等,这使得GObject具有很好的跨语言互通性。
来源:嵌入式大杂烩