本文转自tempid2008
Glib是一种底层库,创建 GDK 和 GTK
应用程序时该库可提供许多有用的定义和函数。它们包括基本类型及限制的定义、标准宏、类型转换、字节序、存储分配、警告和断言、消息记录、计时器、字符串
工具 (string utilities)、挂钩 (hook)
函数、一个句法扫描器、动态加载模块和自动字符串补全,它也定义了许多数据结构(及其相应的操作),包括存储块、双向链表、单向链表、哈希表、串(动态增
长)、串块(串的组)、数组(大小可随元素的加入而增长)、平衡二叉树、N 叉树、夸克
(quark,一种字符串和其唯一的整数标识之间的双向关联)、键数据列表(可由字符串或整数标识访问的数据元素列表)、关系和元组(可通过任一位置号索
引的数据表格)以及缓存 (cache)。
下面将总结Glib库函数的一些功能,没有包括所有函数,数据结构或操作。有关Glib库的更完整的信息请看 Glib 文档。你可以从 下载得到。
1.定义
许多标准类型的极值定义是:
G_MINFLOAT
G_MAXFLOAT
G_MINDOUBLE
G_MAXDOUBLE
G_MINSHORT
G_MAXSHORT
G_MININT
G_MAXINT
G_MINLONG
G_MAXLONG
下面的 typedefs 也是定义。余下未定义的则根据硬件平台的不同而动态设置。请记住如果要想使程序具有可移植性就不要计算指针的大小。一个指针在 Alpha 上是 8 个字节,而在 Intel 80x86 系列 cpu 上是 4 个字节。
char gchar;
short gshort;
long glong;
int gint;
char gboolean;
unsigned char guchar;
unsigned short gushort;
unsigned long gulong;
unsigned int guint;
float gfloat;
double gdouble;
long double gldouble;
void* gpointer;
gint8
guint8
gint16
guint16
gint32
guint32
2.双向链表
以下的函数用于创建、管理和销毁标准双向链表。链表中每个元素都包含一块数据和指向前后元素的指针。这使得通过链表的双向移动变的容易。数据项
的类型是"gpointer",意指数据可为一指向实际数据的指针或 (通过类型转换) 为一数值(但不要设想 int 和 gpointer
有相同的大小!)。这些函数在内部按块为链表元素分配空间,这比单为每个元素分配空间更有效率。
不存在专用于创建列表的函数。而是简单地创建一个类型为 Glist* 的变量,并把它的值设置为 NULL;NULL被当作空表。
向链表中加入一个新元素,使用函数 g_list_append()、g_list_prepend()、g_list_insert()
或 g_list_insert_sorted()
。无论如何,函数都接收一个指向表头的指针作为参数,并返回一个指向表头的指针(可能和接收的指针不同)。因此,对所有添加或撤除链表元素的操作,一定要
保存返回值!
GList *g_list_append( GList *list, gpointer data );
此函数把一个新元素(具有值data)加到链表尾。
GList *g_list_prepend( GList *list, gpointer data );
此函数把一个新元素(具有值data)加到链表头。
GList *g_list_insert( GList *list, gpointer data, gint position);
此函数插入一个新元素(具有值data)到链表中指定位置,如果位置是 0,它和g_list_prepend() 函数作用相同,如果位置,它和 g_list_append() 函数作用相同。
GList *g_list_remove( GList *list, gpointer data);
此函数从表中移除一个具有值data的元素,如果该元素不存在,链表不变。
void g_list_free( GList *list );
此函数释放由Glist使用的所有存储区,如果表元素空间是通过动态分配的,则应
首先被释放。
还有许多其它支持双向链表的Glib函数;查看文档获得更多的信息。这儿列出几个更有用的函数的声明:
GList *g_list_remove_link( GList *list, GList *link );
GList *g_list_reverse( GList *list );
GList *g_list_nth( GList *list, gint n );
GList *g_list_find( GList *list, gpointer data );
GList *g_list_last( GList *list );
GList *g_list_first( GList *list );
gint g_list_length( GList *list );
void g_list_foreach( GList *list, GFunc func, gpointer user_data );
3.单向链表
以上的许多函数用于单向链表是一样的。下面是链表操作函数的部分列表:
GSList *g_slist_append( GSList *list,
gpointer data );
GSList *g_slist_prepend( GSList *list,
gpointer data );
GSList *g_slist_insert( GSList *list,
gpointer data,
gint position );
GSList *g_slist_remove( GSList *list,
gpointer data );
GSList *g_slist_remove_link( GSList *list,
GSList *link );
GSList *g_slist_reverse( GSList *list );
GSList *g_slist_nth( GSList *list,
gint n );
GSList *g_slist_find( GSList *list,
gpointer data );
GSList *g_slist_last( GSList *list );
gint g_slist_length( GSList *list );
void g_slist_foreach( GSList *list,
GFunc func,
gpointer user_data );
4.存储管理
gpointer g_malloc( gulong size );
这是 malloc() 函数的替代函数,不需要检查返回值,因为此函数已替你做这件事了。如果存储分配因任何原因失败,应用程序将被终止。
gpointer g_malloc0( gulong size );
和上一函数相同,但在返回指向所分配存储块的指针之前,将该存储块清 0。
gpointer g_realloc( gpointer mem,
gulong size );
重新分配由mem开始,大小为 size 字节的存储块。明显地,该存储块先前已被分配。
void g_free( gpointer mem );
释放分配的存储块。这很简单。如果 mem 为 NULL,则直接返回。
void g_mem_profile( void );
把用过的存储块的内容转储到一个文件中。但要这样做,需要将#define MEM_PROFILE加到文件 glib/gmem.c 的开始处,然后重新运行命令 make 和make install。
void g_mem_check( gpointer mem );
检查存储位置的有效性。需要将#define MEM_CHECK加到文件 glib/gmem.c 的开始
处,然后重新运行命令 make 和 make install。
5.计时器
计时器函数可用于对操作计时(即查看操作所耗费的时间)。首先用 g_timer_new() 函数建立一个新计时器,然后用
g_timer_start() 函数启动计时,用g_timer_stop() 停止计时,用 g_timer_elapsed()
函数决定所耗的时间。
GTimer *g_timer_new( void );
void g_timer_destroy( GTimer *timer );
void g_timer_start( GTimer *timer );
void g_timer_stop( GTimer *timer );
void g_timer_reset( GTimer *timer );
gdouble g_timer_elapsed( GTimer *timer,
gulong *microseconds );
6.字符串处理
GLib 定义了一个叫做 GString 的新类型,该类型相似于标准 C
中的string,但可以自动增长。字符串数据以null结尾。该类型可以防止程序中的缓冲区溢出错误。这是一个非常重要的特性,因此我推荐使用
GString。GString 有一简单定义:
struct GString
{
gchar *str; /* 指向当前以‘\0’结尾的字符串。 */
gint len; /* 当前长度 */
};
如你所预想的,有许多对一个 GString 型字符串的操作。
GString *g_string_new( gchar *init );
这个函数构造一个 GString 型字符串,它把 init指向的字符串值复制到 GString 型字符串中,返回一个指向它的指针。建一个初始为空的 GString 型字符串则传递一个 NULL 作为参数。
void g_string_free( GString *string,
gint free_segment );
该函数释放给定的 GString 型字符串的存储空间。如果参数 free_segment 为TRUE,也释放其字符数据。
GString *g_string_assign( GString *lval,
const gchar *rval );
该函数将 rval 中的字符复制到 lval 中,覆盖 lval 中以前的内容。注意为装下复制的字符串,lval 会变长,这是和标准的 strcpy() 数不一样的。
以下函数的功能是相当明显的(带有_c的版本接受一个字符而不是一个字符串):
GString *g_string_truncate( GString *string,
gint len );
GString *g_string_append( GString *string,
gchar *val );
GString *g_string_append_c( GString *string,
gchar c );
GString *g_string_prepend( GString *string,
gchar *val );
GString *g_string_prepend_c( GString *string,
gchar c );
void g_string_sprintf( GString *string,
gchar *fmt,
...);
void g_string_sprintfa ( GString *string,
gchar *fmt,
... );
7.实用程序和错误处理函数
gchar *g_strdup( const gchar *str );
替代strdup函数。把原字符串内容复制到新分配的存储块中,返回指向它的指针。
gchar *g_strerror( gint errnum );
我推荐使用此函数处理所有错误信息,它比 perror() 和其它类似函数更好,更具
可移植性。此函数的输出通常为如下格式:
program name:function that failed:file or further description:strerror
这里有一个在我们的hello_world程序中调用此函数的示例:
g_print("hello_world:open:%s:%s\n", filename, g_strerror(errno));
void g_error( gchar *format, ... );
打印错误信息。格式同于 printf,但在错误信息前加上了"** ERROR **",并且退
出程序。仅用在致命错误上。
void g_warning( gchar *format, ... );
和前一函数功能相同,只是错误信息前是 " ** WARNING ** ",且不退出程序。
void g_message( gchar *format, ... );
在传递的字符串前打印 "message:"
void g_print( gchar *format, ... );
替代 printf() 函数。
本章最后一个函数:
gchar *g_strsignal( gint signum );
对所给信号的号码打印出相应的信号名称。在通用信号处理函数中有用