最近打算开始学习GObject,所以转载几篇GObject的文章。
原文如下:
去年,曾经用了 10 多天的时间学习了一番 GObject,当时疏于心得的总结,而现在已经忘记的差不多了。
最近因为观察到 GtkGLExt 项目没有跟进 gtk+-3.0 的意思,便想自己动手,丰衣足食,要么去改造现有的 gtkglext 代码,要么另起炉灶。也许在自由/开源的世界中,期待是可耻的,只有动手才会幸福。但是,这与 GObject 有什么关系?
在 GTK+ 的众多底层库中,GObject 与 GLib 是两块基石,在它们之上矗立着 Cairo、Pango、Clutter、GDK、ATK 等支柱,还有 GtkGLExt 这棵对我而言非常重要的小支柱,没有它我便不知道该如何在 GTK+ 中直接绘制 OpenGL 三维图形。事实上,除了 GtkGLExt 之外,还有 Cogl 可供选择,后者是对 OpenGL 进行抽象封装,主要是为了方便 Clutter 在其上层创造场景图结构。既然是封装,那么就需要容器,Cogl 所使用的容器便是 GObject。
也许你对 GTK+ 支持 OpenGL 的事情并不感兴趣,那么我们便将话题转回至 GObject,并提出这样一个问题:既然 GObject 如此重要,那么它究竟是做什么的?
简单的说,GObject 是一个程序库,它可以帮助我们使用 C 语言编写面向对象程序。
很多人被灌输了这样一种概念:要写面向对象程序,那么就需要学习一种面向对象编程语言,例如 C++、Java、C# 等等,而 C 语言是用来编写结构化程序的。事实上,面向对象只是一种编程思想,不是一种编程语言。换句话说,面向对象是一种游戏规则,它不是游戏。GObject 告诉我们,使用 C 语言编写程序时,可以运用面向对象这种编程思想。
从宏观层面上来论证 GObject 与 C++、Java 之类的面向对象编程语言相比具备何种优越性,这是没有意义的。最优化理论中有一个“没有免费的午餐”定理,大意是说没有一种方法可以适合于全部问题,应当选择合适的方法,并将它放在合适的地方使用。这个定理对于编程语言的选择与使用也有效,因为选择某种最合适的语言,本身就是一个最优化问题。
假如我们选择了 GObject,它最适合处理那些问题?
首先,与操作系统层面相距较近的程序设计,即系统程序设计,例如上文所列举的 GTK+ 及其支柱,使用 GObject 模拟的面向对象机制可以简化程序逻辑结构,同时还能保证程序的性能以及系统接口直接调用。最主要的是,系统程序员大都熟悉 C 语言,沟通较为方便。
其次,有时为了兼顾程序性能与开发效率,会对程序结构进行分层设计,底层模块采用 C 程序库实现,上层则使用动态语言或函数式语言实现,此时使用 GObject 除了可以简化底层模块的逻辑结构,还可以通过 GObject 与上层模块进行胶合。现在,GNOME 3 项目提供了 GObject Introspection 技术,专门用于处理 C + GObject 所实现的程序与上层动态语言或函数式语言的胶合问题 [1]。另外,GNOME 3 项目还实现了两种新的语言 Vala 和 Genie,前者语法类似 C#,后者语法类似 Python,使用它们所编写的程序源码,利用相应的编译器便可以生成 C + GObject 代码,进而可以编译为 C 程序[2, 3]。
那么 GObject 容易掌握么?我认为它应该很容易学习和使用,就像网络上许多人很轻易的诟病它非常繁琐难用一样容易。在打算掌握任何一种技术之前,如果不相信它是简单的,内心深处便会滋生一种逃避的意识。我们也可以例证,如果 GObject 真的很难理解和应用,怎么会存在那么多基于 GObject 实现的程序,难道那些程序的作者皆为天才抑或疯子?这种概率实在太小了。
事实上,GObject 是被人为的复杂化了。因为很多学习 GObject 的人,一上来就奔着要全面洞悉 GObject 的实现原理与细节,但是又缺乏足够的耐心和基础知识。如果换一个角度来考虑这个问题,作为初学者,在学习 C++、Java 之类的面向对象编程语言之时,我们有打算直接潜心理解这些语言的内部实现吗?我们大都是要从 Hello world 之类的示例起步的。对于 GObject 的学习也应当如此。
~ END ~