Pine Blog

GLIB用户指南-概述

1.Glib是什么?

gnome是基于gtk+开发的一套桌面环境,gnome和KDE作为两大最流行的桌面环境,在全世界广泛使用。只要是在Linux下工作的开发人员,对于gtk+一定不陌生。而对于glib,这个gtk+下的无名英雄,其功能强大却鲜为人知。今天,在这里简要介绍一下,如果你是开发人员,看完本文,相信你会爱上它的。
glib
glib不是gllibc,尽管两者都是基于(L)GPL的开源软件。但这一字之差却误之千里,glibc是GNU实现的一套标准C的库函数,而glib是gtk+的一套函数库。在linux平台上,像其它任何软件一样,glib依赖于glibc。

glib不是一个学院派的东西,也不是凭空想出来的,完全是在开发gtk+的过程中,慢慢总结和完善的结果。如果你是一个工作3年以上的C语言程序员,现在让你讲讲写程序的苦恼,你可能有很多话要说,但如果你有时间研究一下glib,你会发现,很多苦恼已不再成其为苦恼,glib里很多东西正是你期望已经久的。

gobject是glib的精粹,glib是用C实现的,但在很大程序是基于面向对象思想设计的,gobject是所有类的基类。signal在其中也是一大特色,signal与操作系统中的signal并不一样,它是类似消息一样的东西,让消息在各个对象间传递,但尽量降低对象间的耦合。仔细读一下它的代码,唯一想说的话就是“绝!”。

2.GLib 的范畴

首先研究 GLib 的范畴。
GLib 是一个提供了很多实用定义和函数的底层程序库,包括基本类型及其限定的定义、标准宏、类型转化、字节次序、内存分配、警告与断言、 消息日志、计时器、字符工具、钩子函数、词法扫描器、模块的动态加载,以及自动的字符串补齐。
GLib 还定义了很多数据结构(以及它们相关的操作),包括:

  • 内存块(Memory chunks)
  • 双向链表(Doubly-linked lists)
  • 单向链表(Singly-linked lists)
  • 散列表(Hash tables)
  • 字符串(Strings,可以动态增长)
  • 字符块(String chunks,成组的字符串)
  • 数组(Arrays,当增加元素时其大小能够增长)
  • 平衡二叉树(Balanced binary trees)
  • N-叉树(N-ary trees)
  • Quarks(字符串和唯一整型标识符的双向关联)
  • 有关键字的数据列表(Keyed data lists,通过字符串或者整型 id 访问其数据元素的列表)
  • 关系(Relations)和元组(tuples)(可以由任意数目的域进行索引的数据表)
  • 缓存

3.管理数据

每个程序都必须管理数据

编写程序是为了处理数据。程序可能会从文件中读出一个名字列表、通过一个图形用户界面向用户询问某些数据,或者从一个外部的硬件设备加载数据。 但数据一旦到了程序中,就需要保持对它的追踪。用来管理数据的函数和变量称为 数据结构 或 容器。

如果使用 C 编写代码,那么您会发现它极其缺乏复杂的数据结构。当然,有很多存储数据的简单方法:

  • 基本类型 —— int、float、char 等等。
  • 枚举(enum),可以保存整数的一系列符号名称。
  • 数组(array),这是 C 中最灵活的数据结构。

数组可以保存基本类型的数据,或者一系列任意类型的数据,或者指向任意类型数据的指针。
但是数组也有很多局限性。它们的大小不能改变,所以,如果为一个拥有十个元素的数组分配了内存,却发现需要向其中放置十一个元素, 那么就得创建一个新数组,将旧的元素拷贝过来,然后添加并新的元素。如果要遍历数组中的每一个元素,那么,或者需要始终知道数组中有 多少个元素,或者要确保在数组的末尾处有某种“数组结束”标记,以使得您能够知道何时停止。

通过使用链表和二叉树等标准容器,在 C 中保持对数据的追踪的问题已经多次得到解决。每一位刚开始学习计算机科学专业的学生都会使用一个 数据结构类;教师肯定会布置一系列编写那些容器的实现的练习。在编写这些数据结构时,学生会意识到它们是多么难以处理;粗心的学生经常会 犯诸如悬空指针(dangling pointer)和重复 释放内存(free) 的错误。
编写单元测试会有很大帮助,但是,总的来说,为每个新程序重新编写相同的数据结构是一个费力不讨好的任务。

4.内置的数据结构

简言之就是,在什么地方内置数据结构会有所帮助。有一些语言会内置附带这些容器。C++ 包含标准模板库(Standard Template Library,STL), 它有一个容器类工具集,比如列表、优先队列、集合(set)和映射。另外,这些容器是 类型-安全(type-safe) 的,也就是说,您只能 向创建的每一个容器对象中放入一种类型的元素。这就使得它们的使用更为安全,并避免了 C 所要求的很多冗长的强制类型转换。并且,STL 包含了 很多遍历工具和排序工具,这样就使得容器的使用更为简单。

Java 编程环境也附带了一组容器类。The java.util 程序包包含 ArrayList、 HashMap、TreeSet 以及其他各种标准结构。它还包括有用于对数据进行一般排序、创建 不变集合的工具,以及其他各种便利工具。
不过,C 并没有内置容器支持;您或者只能自己编写,或者使用其他人的数据结构程序库。
幸运的是,GLib 是一个能够满足此需要的优秀的、免费的、开放源代码的程序库。它包含了大部分标准数据结构,以及在程序中有效处理数据的很多实用工具。 它诞生于 1996 年,从而经过了彻底地测试,并在发展过程中增加了很多实用功能。

5.100 字以内(或者更少)的算法分析

对容器的不同操作需要不同长度的时间。例如,在一个长的列表中,访问第一个元素要快于对同一列表进行排序。用来描述完成这些操作所需时间的 符号称为 O-notation。这个话题需要计算机科学专业的学生用一个学期的时间去研究,但是,简要地讲,O-notation 是对操作的最坏情况的 分析。换句话说,它对完成某个操作所需要的 最长 时间进行度量。它被证明是度量数据结构操作的有效途径,因为经常会遇到最坏情况的操作 (比如当您搜索某个列表而却没有找到所找查找的条目时)。

接下来论述了一些 O-notation 示例,可以将一副扑克牌在桌子上排列一行:

  • O(1) —— 选择第一张牌。 O(1) 也称为“线性时间(constant
    time)”,因为不管在列表中有多少张牌,取得第一张牌的时间都是相同的。
  • O(n) —— 翻转每一张牌。O(n) 被称为“线性时间(linear time)”,因为 随着牌的数目增加,完成操作所需时间线性增加。
  • O(n!) —— 创建一个全部扑克牌所有可能排列的列表。每向列表添加一张新牌,排列的数目 都会阶乘式增加。

您会发现,在整个教程都提及关于不同数据结构操作的 O-notation。 了解特定数据结构上特定操作的开销,能够帮助您更明智地选择容器在,最优化应用程序的性能。

6.编译 GLib 程序

如果在研究那些示例时编译并运行它们,那么您将通过本文学到更多。由于它们要使用 GLib,所以编译器需要知道 GLib 头文件和程序库在哪里, 以使其能够解析 GLib 定义的类型。这个简单的程序初始化一个双向链表并向其中添加一个字符串:

//ex-compile.c
#include <glib.h>
int main(int argc, char** argv) {
 GList* list = NULL;
 list = g_list_append(list, "Hello world!");
 printf("The first item is '%s'\n", g_list_first(list)->data);
 return 0;
}

可以通过调用 GCC 来编译这个程序,如下:

$ gcc -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  -lglib-2.0 -o ex-compile ex-compile.c

运行它,查看期望的输出:

$ ./ex-compile
The first item is 'Hello world!'
$

不过,那是一个非常难用的 GCC 调用。更简单的方式是让 GCC 指向 GLib 程序库。
使用 pkg-config
手工指定程序库的位置容易出错而且很冗长,所以大部分现代的 Linux 发行版本都附带了 pkgconfig 工具来帮助简化此问题。 可以使用 pkgconfig 来编译上面的程序,如下:

$ gcc 'pkg-config --cflags --libs glib-2.0' -o ex-compile ex-compile.c

输出与先前相同:

$ ./ex-compile
The first item is 'Hello world!'
$

注意,现在不必再指定 GLib 头文件的路径;pkgconfig 的 --cflags 选项会完成此任务。 使用 --libs 选项指定的程序库也是如此。当然,没有任何神密之处;pkgconfig 只是通过一个配置 文件读取出程序库和头文件的位置。在 Fedora Core 3 系统中,pkgconfig 文件位于 /usr/lib/pkgconfig 目录下, glib-2.0.pc 文件类似如下:

$ cat /usr/lib/pkgconfig/glib-2.0.pc
 prefix=/usr
 exec_prefix=/usr
 libdir=/usr/lib
 includedir=/usr/include

 glib_genmarshal=glib-genmarshal
 gobject_query=gobject-query
 glib_mkenums=glib-mkenums

 Name: GLib
 Description: C Utility Library
 Version: 2.4.7
 Libs: -L${libdir} -lglib-2.0
 Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include

这样,所有信息都由一个中间层隐藏起来。如果恰巧使用了一个不支持 pkgconfig 的 Linux 发行版本,那么随时可以重新直接为 GCC 指定头文件和程序库。

7.谁在用GLib

仅仅列举出 GLib 容器并展示示例用法可能还不够,所以本教程还包含了 GLib 在一些开放源代码的应用程序中的现实应用:

  • Gaim 是一款流行的实时消息客户机,它在 SourceForge 上的下载次数每个月都会超过二十五次。
  • GIMP(Graphical Image Manipulation Program)是 GLib 本身的出发点(starting
    point);它是一款广为应用的图像处理程序,从 1996 年开始 一直得到公众的共同开发。
  • Evolution 是一款极好的个人信息管理器(PIM),可以追踪电子邮件、联系人、任务和约会。

研究 GLib 在这些流行的应用程序中的应用还会让您有机会了解一些编码习惯;不仅能知道函数的名字是什么,您还能够了解通常如何使用它们。 您将会熟悉将要使用的容器,而且甚至会注意到在某些情况下有人选择了并不最适于某任务的容器。

GLib 还拥有很多约定(conventions)及工具宏。在学习的过程中,您将发现使用并解释了其中的很多。不必尝试一开始就将它们完全记住,而只需要 在进行过程中去学习它们,在示例中去了解它们。

文章转载自:https://blog.csdn.net/l197803/article/details/138244885?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-138244885-blog-52932358.235%5Ev43%5Epc_blog_bottom_relevance_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-138244885-blog-52932358.235%5Ev43%5Epc_blog_bottom_relevance_base2&utm_relevant_index=5,如有问题请联系删除。

未经允许不得转载:Pine Blog » GLIB用户指南-概述

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Pine Blog
Anywhere, Anytime
E-mail:59054872@qq.com
苏ICP备15059480号-1