GObject

关注
义项:GTK的面向对象编程库
GObject

GObject(GLib Object System)是一个以 LGPL 许可发布的自由软件库,为 C 语言提供了一套可移植的对象系统,并支持跨语言的透明互操作[1]。它只依赖 GLib 和 libc,是 GNOME 桌面的基石,被 GTK、Pango、GStreamer 以及大量 GNOME 库和应用程序使用。其底层是名为 GType 的动态类型系统,上层还提供信号、属性与闭包机制,使 C 代码能够以面向对象的方式组织,并让他语言绑定得以自动生成[2]。

百科 图文
目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

GObject 是 GLib 提供的对象系统实现,它建立在 GType、GValue、GParameter、GClosure 与 GSignal 等模块之上,为 C 程序补齐了对象概念。在 GTK 的依赖体系里,GObject 被定义为提供类型系统、一组包含对象类型的基础类型以及信号系统的库。

按照 GLib 参考手册的描述,GLib 对象系统为跨语言映射而设计,其构成要素包括一个可注册任意深度的单继承类型与结构化类型接口的通用类型系统、一批整数与浮点等基础类型的实现、作为对象层次根基的 GObject 基础类型、允许用户定制虚方法的信号系统,以及可容纳全部基础类型的参数与值系统[2]。

原理

GObject 的底层是泛型动态类型系统 GType,它保存所有对象的运行时描述,供胶水代码实现语言绑定使用;该系统既能处理任意单继承的类层次,也能处理不透明指针、字符串、各种宽度的整数与浮点数等非类类型[1]。GType 知道如何复制、赋值与释放任何已注册类型的值:对整数这类非引用计数的值直接操作,对引用计数对象则增加其引用计数,对复杂的非引用计数对象则分配内存建立副本[1]。实际对象层次通过 g_object_new() 创建,而 g_type_create_instance() 仅限于基础类型的实现者使用[3]。

每个 GObject 类至少由两个结构实现。类结构相当于 C++ 的虚函数表,以父类的类结构开头,其后是各虚方法的函数指针;实例结构为每个对象实例各存一份,同样以父类的实例结构开头,随后是相当于 C++ 成员变量的实例数据[4]。由于 C 结构没有访问修饰符,封装通常通过在实例结构中放置一个约定名为 _priv 的私有数据指针来实现,若该私有结构也在 GType 中注册,对象系统会自动为其分配空间[4]。

GObject 的消息机制由闭包与信号两部分组成。闭包是回调的推广形式,除 C 与 C++ 外,在提供绑定的语言中也可用;信号则是调用闭包的主要途径,对象向类型系统注册监听者并建立信号与闭包的对应关系,信号发出时相应闭包被调用[4]。信号按类型引入并以字符串标识,父类型的信号在派生类型中同样可用[5]。参考手册说明,信号发射依次经过类方法处理器与用户提供的处理器等阶段,处理器可以通过屏蔽、解除屏蔽而在发射过程中被跳过[5]。

GType 的接口与 Java 的接口类似,用于描述多个类共同遵守的 API;声明接口需注册一个派生自 GTypeInterface 的不可实例化类类型,接口结构中包含各方法的函数指针[6]。实例化与终结过程由类型系统按次序驱动:首次创建实例时先在继承链上调用 base_init、再对目标类型调用 class_init,每次创建实例会调用 instance_init,最后的实例释放则触发接口销毁与相应的终结函数[6]。

发展历程

在 GTK+ 2.0 之前,GObject 的代码属于 GTK+ 的一部分,当时并未使用 GObject 这个名字,公共基类称为 GtkObject[1]。由于对象系统的适用范围比图形界面更广,GTK+ 2.0 发布时把它抽取为独立库,GtkObject 中与图形界面无关的部分被移入新的公共基类 GObject[1]。自 2002 年 3 月 11 日即 GTK+ 2.0 发布之日起,GObject 一直以独立库的形式存在,并被许多非图形界面的命令行与服务器程序采用[1]。

接口机制是在 GLib 2.4 中加入的,该版本于 2004 年 3 月 16 日发布,因此 GObject 的接口类型在较长时间里使用得不普遍,GIMP 是使用它的项目之一[7]。GType 系统本身也逐步补充新能力,例如 g_type_add_instance_private 与 g_type_add_class_private 等接口在 GLib 2.24 前后加入,用于为实例与类注册私有结构[3]。自 GLib 2.36 起类型系统自动初始化,原先用于初始化的 g_type_init() 不再执行任何操作[3]。

围绕 GObject 的绑定与开发工具也相继出现。GObject Introspection 项目为 C 库的 API 提供机器可读的自省数据,用于自动生成绑定、校验 API 以及生成文档,其数据以 typelib 格式分发,供 JavaScript、Python 等动态语言生成绑定[8]。基于该机制的绑定包括 Python 的 PyGObject 与 JavaScript 的 GJS[9]。此外还有 GObject Builder 这类代码生成工具,以及能编译为 C 的 Vala 语言,用于缓解手写样板代码的负担[4]。

应用

C 语言与 GObject 的组合被用于众多自由软件项目,包括 GNOME 桌面、GTK 工具包与 GIMP 图像处理程序[4]。GObject 同样是 GStreamer 多媒体框架与 GNOME、XFCE 桌面等开源项目的基础,GTK 及其若干依赖也建立在该库之上。GLib、GObject、GModule 与 Gio 的自省数据被打包为 typelib 格式的分发单元,供上层绑定使用。

在语言绑定方面,GObject 的观念可以较自然地映射到 C++、Java、Ruby、Python、Common Lisp 与 .NET/Mono 等语言的原生对象系统,因此为写得规范的 GObject 库建立语言绑定通常相对省力[4]。GObject Introspection 要求为函数参数标注所有权转移等信息,以便为 Python、JavaScript、Vala、C++、Rust 等语言自动生成正确的绑定[10]。除语言绑定外,这类运行时元对象信息也被 Glade 一类界面设计工具使用,用以载入提供 GObject 类的共享库并取得类的属性列表与类型信息[4]。

由于 GObject 只依赖 GLib 和 libc,其源代码位于 GLib 的源码树中并与 GLib 一同发行,因此采用与 GLib 相同的版本号,常见的发行版做法是把 GObject 并入 GLib 的软件包,例如 Debian 将其放在 libglib2.0 套件家族中[1]。

局限

在 C 语言中定义 GObject 类的过程冗长,需要手写类型转换宏和不易理解的类型注册代码等大量样板内容;编写一个子类即使只是继承 GObject,也可能需要书写或复制上百行代码[4]。其学习曲线较陡,习惯高层面向对象语言的开发者在 C 中操作 GObject 时常常觉得繁琐,为此出现了 GObject Builder 与 Vala 等以模板或源到源编译方式减少样板代码的工具[4]。

GObject 在 C 语言中实现面向对象语义,这也给工具链带来困难:类型层次、属性与信号等信息既不易从源码中可靠提取,也不易从编译产物中得到,只能在运行时让程序描述自身[11]。有开发者认为 GObject 未采用类似 Qt 的高层接口描述语言配合预处理器生成 C 代码的方案,而要求直接手写样板代码,导致可读性与可维护性不佳,Vala 的诞生部分即源于此类困扰[11]。

与 C++ 和 Objective-C 相比,GObject 只是库而非语言扩展,不为语言增加新的语法或编译器特性,因此使用它时经常需要显式类型转换;同时它和 Java 一样不提供多重继承[1]。在跨语言互操作上,为动态语言编写绑定时,所有权转移与生命周期难以描述的函数同样是 C 语言中较难正确使用的函数[10]。

参见

  • GLib —— GObject 所依赖并与之共同发行的基础实用库。

  • GTK —— 使用 GObject 提供面向对象 C 接口的图形界面工具包。

  • GNOME —— 以 GObject 为基石构建的桌面环境。

  • GStreamer —— 建立于 GObject 之上的多媒体框架。

  • Vala —— 可编译为 C 代码、用于简化 GObject 开发的编程语言。

  • PyGObject —— 基于 GObject Introspection 的 Python 语言绑定。

参考资料

  1. GObject [引用日期2026-10-14]
  2. Introduction [引用日期2026-10-14]
  3. GObject-2.0 [引用日期2026-10-14]
  4. GObject [引用日期2026-10-14]
  5. GObject: Signals [引用日期2026-10-14]
  6. GObject: Type System Concepts [引用日期2026-10-14]
  7. GObject [引用日期2026-10-14]
  8. 软件包:gir1.2-glib-2.0(2.88.3-3 以及其他的) [引用日期2026-10-14]
  9. Users [引用日期2026-10-14]
  10. Semantics [引用日期2026-10-14]
  11. marc.info 上的网页 [引用日期2026-10-14]
词条评价
词条统计

浏览次数:2 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-13T20:31:07Z

历史版本

本条目引用的词条
GLib GTK GNOME GStreamer Vala PyGObject