Glib是一种底层库,创建 GDK 和 GTK 应用程序时该库可提供许多有用的定义和函数。它们包括基本类型及限制的定义、标准宏、类型转换、字节序、存储分配、警告和断言、消息记录、计时器、字符串 工具 (string utilities)、挂钩 (hook) 函数、一个句法扫描器、动态加载模块和自动字符串补全,它也定义了许多数据结构(及其相应的操作),包括存储块、双向链表、单向链表、哈希表、串(动态增 长)、串块(串的组)、数组(大小可随元素的加入而增长)、平衡二叉树、N 叉树、夸克 (quark,一种字符串和其唯一的整数标识之间的双向关联)、键数据列表(可由字符串或整数标识访问的数据元素列表)、关系和元组(可通过任一位置号索引的数据表格)以及缓存 (cache)。在开源世界中,G中很常见的。它代表了GNU (GNU's Not Unix)。像GTK+,GLib,GObject,以及GNOME,还有一些其它的软件包,如Ghostscript和gcc中都充满了G。
必须学习一些GLib的基础知识(libglib-2.0),它为GTK+和GNOME程序提供了基础的数据结构和实用函数。在此会涉及到GLib的结构和API的介绍,同时将会在后面学习GLib's object system(GObject)。在使用GNOME和GTK+的时候,会不可避免的使用GLib,GLib所提供的库和实用工具为编程提供了方便,而且很容易移植到其它平台。
GLib Naming Coventions (GLib命名规则)
就像许多其它的库一下,GLib也为了一致性和易读性规范了命名规则。函数的名字一般都是小写的,并且在每部分名字之间加下划线,如g_timer_new(),g_list_append()。并且所有的函数名字都是以g_开头。
在GLib中,所有的函数都有前缀g_。类型名并不包含下划线,并且GLib里面的所有类型组件都是以大写字母G开头的,如GTimer,GList。但GLib中的基本类型是值得注意的例外。如果某个函数主要是操作某个特定的类型的话,这个函数的前缀就与相应的类型相匹配。例如,g_timer_*就是操作GTimer类型。g_list_*就是操作GList类型。这些规则听起来比实际要复杂。
下面将总结Glib库函数的一些功能,没有包括所有函数,数据结构或操作。有关Glib库的更完整的信息请看 Glib 文档,也可以从GTK的主站上下载得到。
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
Basic Types 基本类型讲解1
在开始使用 GLib 之前,首先要适应 GLib 的基本类型。或许很想知道为什么使用 guchar 要比使用 unsigned char 好。如果程序一直待在同一个平台上执行,那么使用 guchar 与使用 unsigned char 并没有实质的差别。但如果想编写出在不同平台之间移植的程序,如 Windows 和 Unix 之间。那就会很感谢 GLib 将基本类型给抽象出来了。
例如想在所有可能的平台上定义 16 位的无符号整型,使用 C 语言的话可能看起来很麻烦。但幸运的是 GLib 帮忙处理了这些。所有的基本类型在下面的表格中列出。
要使用 GLib 和它的类型,必须要在源码中包含 glib.h:
#include <glib.h>
gpointer 和 gconstpointer 类型在 GLib 的数据结构中经常出现,这两个是无类型的内存指针。在 GLib 中,函数负责检查这两个指针的类型,程序员和编译器并不管这些。这在回调函数以及排序和遍历中比较的时候尤其方便。
在 GLib 的头文件中为 gboolean 类型定义了 TRUE 和 FALSE 常量。在使用这些常量的时候,不要使用比较运算符。例如要用:if (my_gboolean) ,而不是:if (my_gboolean == TRUE) 。
GLib Type | Corresponding Type in C |
gchar | char |
ugchar | unsigned char |
gint | int |
guint | unsigned int |
gshort | short |
gushort | unsigned short |
glong | long |
gulong | unsigned long |
gfloat | float |
gdouble | double |
gint8 | int, 8 bits wide |
guint8 | unsigned int, 8 bits wide |
gint16 | int, 16 bits wide |
guint16 | unsigned int, 16 bits wide |
gint32 | int, 32 bits wide |
guint32 | unsigned int, 32 bits wide |
gint64 | int, 64 bits wide |
guint64 | unsigned int, 64 bits wide |
gpointer | void *, untyped pointer |
gconstpointer | const void *, constant untyped pointer |
gboolean | Boolean value, either TRUE or FALSE |
Basic Utilities
( 基本函数 , 这个 Utilities 不知道如何译,就写成函数吧,因为后面确实在讲函数…… )为了简化程序与 C 语言以及系统的交互,GLib 提供了大量的函数。要了解 GLib 的函数处理数据结构部分,请看后面章节。
注意: 如果有一些特殊的原因要使用函数的返回值的话,可以使用 g_try_malloc() 和 g_try_realloc() ,如果出错的时候,它们会返回 NULL 。这可以在某些不是非常关键的地方使用 ( 如某些用来提高性能的额外缓冲区 ) ,或者某些测试的时候。
如果想覆盖 GLib 的保护机制,必须要清楚在做什么。对大多数程序来说,这些像 g_malloc() 的普通函数能节约大量的代码、错误、以及时间。
一般情况下,没有必要为 malloc 或 g_malloc 指定具体的要申请的块的大小。一般都是使用 sizeof() 来告诉编译器或运行时系统申请某种类型的某个倍数。为了与数据类型相符,必须要将 malloc() 返回值进行强制转换。强制转换要用大量的括号和星号,所以 GLib 提供了一些宏,如 g_new(),g_new0() 以及 g_renew() 。
内存管理
如果使用 GLib 提供的内存管理例程,它可以避免你处理很多让你头痛的事。GLib 提供了的附加的错误检查与侦测,在下面的表格中为 C 程序员提供了一个参考。可以使用 g_malloc(),g_realloc(),g_free() 来代替 malloc(),realloc(),free(),它们提供了相同的处理方式。为了将申请的内存在使用前清零,可以使用 g_malloc0() 。 注意,它的语法看起来像 malloc ,而不是 calloc() 。
GLib Function | Corresponding C Function |
gpointer g_malloc(gulong n_bytes) | void *malloc(size_t size) with error handling |
gpointer g_malloc0(gulong n_bytes) | like malloc(), but initializes memory as in calloc() |
gpointer g_try_malloc(gulong n_bytes) | like malloc() without error checking |
gpointer g_realloc(gpointer mem, gulong n_bytes) | void *realloc(void *ptr, size_t size) with error checking |
gpointer g_try_realloc(gpointer mem, gulong n_bytes) | realloc() without error checking |
void g_free(gpointer mem) | void free(void *ptr) |
内存块
GUI 程序一般倾向于重复申请大小相同的内存块 (原子) 。而且,那儿有一些相关的原子内存 (atom) 。 GLib 使用了一种称为“ memory chunks ”的方法为程序提供了相应的原子内存。一个内存块由一些原子内存组成的;所以块的大小肯定是原子内存大小的整数倍。
Quarks (夸克)
为了在程序中标识一块数据,一般有两种方式可选:数字或字符串。但是这两者都有一些缺点。数字是非常难以辨认的。如果开始粗略的知道需要多少标签,就可以定义一个枚举类型和一些字符符号。但是没法在运行的时候动态添加标签。
另一方面,可以在运行的时候动态的添加或修改字符串,而且它们是很容易理解的。但是字符串比较要比数字比较花更长的时间,而且在内存中管理字符串有一些你可能不愿意处理的额外麻烦。GLib 提供了 GQuark 类型,它整合了数字的简单和字符串的易用。在它内部,它就是一个易于比较和复制的整形数。GLib 将这些数字映射为字符串,并且可以在任何时间取得字符串所对应的值。
Basic Types 基本类型讲解2
基本类型 — 标准的Glib类型,定义的非常易用和简便。
#include <glib.h>
typedef gboolean;
typedef gpointer;
typedef gconstpointer;
typedef gchar;
typedef guchar;
typedef gint;
typedef guint;
typedef gshort;
typedef gushort;
typedef glong;
typedef gulong;
typedef gint8;
typedef guint8;
typedef gint16;
typedef guint16;
typedef gint32;
typedef guint32;
#define G_HAVE_GINT64
typedef gint64;
GLIB_VAR guint64();
#define G_GINT64_CONSTANT(val)
#define G_GUINT64_CONSTANT(val)
typedef gfloat;
typedef gdouble;
typedef gsize;
typedef gssize;
typedef goffset;
Description 描述
定义一些普通使用类型,可分为4组:
1.不属于标准C的新类型:gboolean, gsize, gssize.
2.可以在任何平台使用的整数:gint8, guint8, gint16, guint16, gint32, guint32, gint64, guint64.
3.与标准C相似但更好用的类型:gpointer, gconstpointer, guchar, guint, gushort, gulong.
4.与标准C基本一致的类型:gchar, gint, gshort, glong, gfloat, gdouble.
Details 详细说明
gboolean
typedef gint gboolean;
标准的boolean类型。它只储存两个值:TRUE和FALSE
gpointer
typedef void* gpointer;
无类型的指针。Gpointer比 void*更好看和更好用。
gconstpointer
typedef const void *gconstpointer;
一个常数的无类型指针。指针的值不能被更改。典型的使用子函数原型上,指出指针所指向的数据是不能被函数更改的。
gchar
typedef char gchar;
和标准C的char类型一致。
guchar
typedef unsigned char guchar;
和标准C的 unsigned char一致。
gint
typedef int gint;
类似标准C的int类型。其值能被设置G_MININT 到 G_MAXINT范围。
guint
typedef unsigned int guint;
类似标准C的unsigned int类型。其值能被设置0到 G_MAXUINT的范围。
gshort
typedef short gshort;
类似标准C的short类型。其值能被设置G_MINSHORT 到 G_MAXSHORT范围。
gushort
typedef unsigned short gushort;
类似标准C的unsigned short类型。其值能被设置0到 G_MAXUSHORT的范围。
glong
typedef long glong;
类似标准C的long类型。其值能被设置G_MINLONG 到 G_MAXLONG范围。
gulong
typedef unsigned long gulong;
类似标准C的unsigned long类型。其值能被设置0到 G_MAXULONG的范围。
gint8
typedef signed char gint8;
在任何平台上都保证是一个有符号8位整数。其取值返回为 -128 到 127
guint8
typedef unsigned char guint8;
在任何平台上都保证是一个无符号8位整数。其取值返回为 0 到 255
gint16
typedef signed short gint16;
在任何平台上都保证是一个有符号16位整数。其取值返回为 -32,768 到 32,767
guint16
typedef unsigned short guint16;
在任何平台上都保证是一个无符号16位整数。其取值返回为 0 到 65,535
gint32
typedef signed int gint32;
在任何平台上都保证是一个有符号32位整数。其取值返回为 -2,147,483,648 到 2,147,483,647
guint32
typedef unsigned int guint32;
在任何平台上都保证是一个无符号32位整数。其取值返回为 0 到 4,294,967,295
gint64
G_GNUC_EXTENSION typedef signed long long gint64;
在任何平台上都保证是一个有符号64位整数。其取值返回为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
guint64()
GLIB_VAR guint64();
在任何平台上都保证是一个无符号32位整数。
其取值返回为 0 到 18,446,744,073,709,551,615
G_GINT64_CONSTANT()
#define G_GINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##LL))
This macro is used to insert 64-bit integer literals into the source code.
val : a literal integer value, e.g. 0x1d636b02300a7aa7U.
G_GUINT64_CONSTANT()
#define G_GUINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##ULL))
This macro is used to insert 64-bit unsigned integer literals into the source code.
val : a literal integer value, e.g. 0x1d636b02300a7aa7U.
Since 2.10
gfloat
typedef float gfloat;
类似标准C的float类型。其值可以设置-G_MAXFLOAT 到 G_MAXFLOAT范围
gdouble
typedef double gdouble;
类似标准C的double类型。其值可以设置-G_MAXDOUBLE 到G_MAXDOUBLE范围
gsize
typedef unsigned int gsize;
一个无符号整形,用来储存sizeof的结果,与C99的size_t类型类似。这个类型能足够存储下一个指针的数据。它常常在32为平台上是32位的,在64位平台上是64位的。
gssize
typedef signed int gssize;
一个有符号gsize,与大多数平台的ssize_t类型类似。
goffset
typedef gint64 goffset;
一个有符号的整形,用来作为文件偏移。类似于C99的off64_t
Since: 2.14
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 );
对所给信号的号码打印出相应的信号名称,在通用信号处理函数中有用到。
使用glib库的程序都应该包含glib的头文件glib.h。
########################### glib基本类型定义 ##############################
整数类型:
gint8、guint8、gint16、guint16、gint32、guint32、gint64、guint64。
不是所有的平台都提供64位整型,如果一个平台有这些, glib会定义G_HAVE_GINT64。
类型gshort、glong、gint和short、long、int完全等价。
布尔类型:
gboolean:它可使代码更易读,因为普通C没有布尔类型。
gboolean可以取两个值:TRUE和FALSE。实际上FALSE定义为0,而TRUE定义为非零值。
字符型:
gchar和char完全一样,只是为了保持一致的命名。
浮点类型:
gfloat、gdouble和float、double完全等价。
指针类型:
gpointer对应于标准C的void *,但是比void *更方便。
指针gconstpointer对应于标准C的const void *(注意,将const void *定义为const gpointer是行不通的)
########################### glib的宏 ##############################
一些常用的宏列表
#include <glib.h>
TRUE
FALSE
NULL
MAX(a, b)
MIN(a, b)
ABS ( x )
CLAMP(x, low, high)
TRUE / FALSE / NULL就是1 / 0 / ( ( v o i d * ) 0 )。
MIN ( ) / MAX ( )返回更小或更大的参数。
ABS ( )返回绝对值。
CLAMP(x,low,high )若X在[low,high]范围内,则等于X;如果X小于low,则返回low;如果X大于high,则返回high。
有些宏只有g l i b拥有,例如在后面要介绍的gpointer-to-gint和gpointer-to-guint。
大多数glib的数据结构都设计成存储一个gpointer。如果想存储指针来动态分配对象,可以这样做。
在某些情况下,需要使用中间类型转换。
//////////////////////////////////////////////////////////////
gint my_int;
gpointer my_pointer;
my_int = 5;
my_pointer = GINT_TO_POINTER(my_int);
printf("We are storing %dn", GPOINTER_TO_INT(my_pointer));
//////////////////////////////////////////////////////////////
这些宏允许在一个指针中存储一个整数,但在一个整数中存储一个指针是不行的。
如果要实现的话,必须在一个长整型中存储指针。
宏列表:
在指针中存储整数的宏
#include <glib.h>
GINT_TO_POINTER ( p )
GPOINTER_TO_INT ( p )
GUINT_TO_POINTER ( p )
GPOINTER_TO_UINT ( p )
调试宏:
定义了G_DISABLE_CHECKS或G_DISABLE_ASSERT之后,编译时它们就会消失.
宏列表:
前提条件检查
#include <glib.h>
g_return_if_fail ( condition )
g_return_val_if_fail(condition, retval)
///////////////////////////////////////////////////////////////////////////////////
使用这些函数很简单,下面的例子是glib中哈希表的实现:
void g_hash_table_foreach (GHashTable *hash_table,GHFunc func,gpointer user_data) {
GHashNode *node;
gint i;
g_return_if_fail (hash_table != NULL);
g_return_if_fail (func != NULL);
for (i = 0; i < hash_table->size; i++)
for (node = hash_table->nodes[i]; node; node = node->next)
(* func) (node->key, node->value, user_data);
}
///////////////////////////////////////////////////////////////////////////////////
宏列表:
断言
#include <glib.h>
g_assert( condition )
g_assert_not_reached ( )
如果执行到这个语句,它会调用abort()退出程序并且(如果环境支持)转储一个可用于调试的core文件。
断言与前提条件检查的区别:
应该断言用来检查函数或库内部的一致性。
g_return_if_fail()确保传递到程序模块的公用接口的值是合法的。
如果断言失败,将返回一条信息,通常应该在包含断言的模块中查找错误;
如果g_return_if_fail()检查失败,通常要在调用这个模块的代码中查找错误。
//////////////////////////////////////////////////////////////////////
下面glib日历计算模块的代码说明了这种差别:
GDate * g_date_new_dmy (GDateDay day, GDateMonth m, GDateYear y) {
GDate *d;
g_return_val_if_fail (g_date_valid_dmy (day, m, y), NULL);
d = g_new (GDate, 1);
d->julian = FALSE;
d->dmy = TRUE;
d->month = m;
d->day = day;
d->year = y;
g_assert (g_date_valid (d));
return d;
}
//////////////////////////////////////////////////////////////////////
开始的预条件检查确保用户传递合理的年月日值;
结尾的断言确保glib构造一个健全的对象,输出健全的值。
断言函数g_assert_not_reached() 用来标识“不可能”的情况,通常用来检测不能处理的
所有可能枚举值的switch语句:
switch (val) {
case FOO_ONE:
break ;
case FOO_TWO:
break ;
default:
gint len;
} ;
用下面的函数创建新的GString变量:
GString *g_string_new( gchar *init );
这个函数创建一个GString,将字符串值init复制到GString中,返回一个指向它的指针。
如果init参数是NULL,创建一个空GString。
void g_string_free( GString *string,gint free_segment );
这个函数释放string所占据的内存。free_segment参数是一个布尔类型变量。
如果free_segment参数是TRUE,它还释放其中的字符数据。
GString *g_string_assign( GString *lval,const gchar *rval );
这个函数将字符从rval复制到lval,销毁lval的原有内容。
注意,如有必要, lval会被加长以容纳字符串的内容。
下面的函数的意义都是显而易见的。其中以_c结尾的函数接受一个字符,而不是字符串。
截取string字符串,生成一个长度为l e n的子串:
GString *g_string_truncate( GString *string,gint len );
将字符串val追加在string后面,返回一个新字符串:
GString *g_string_append( GString *string,gchar *val );
将字符c追加到string后面,返回一个新的字符串:
GString *g_string_append_c( GString *string,gchar c );
将字符串val插入到string前面,生成一个新字符串:
GString *g_string_prepend( GString *string,gchar *val );
将字符c插入到string前面,生成一个新字符串:
GString *g_string_prepend_c( GString *string,gchar c );
将一个格式化的字符串写到string中,类似于标准的sprintf函数:
void g_string_sprintf( GString *string,gchar *fmt,. . . ) ;
将一个格式化字符串追加到string后面,与上一个函数略有不同:
void g_string_sprintfa ( GString *string,gchar *fmt,... );
################################## 计时器函数 ##################################
创建一个新的计时器:
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 );
################################## 错误处理函数 ##################################
gchar *g_strerror( gint errnum );
返回一条对应于给定错误代码的错误字符串信息,例如“ no such process”等。
使用g_strerror函数:
g_print("hello_world:open:%s:%sn", filename, g_strerror(errno));
void g_error( gchar *format, ... );
打印一条错误信息。
格式与printf函数类似,但是它在信息前面添加“ ** ERROR **: ”,然后退出程序。它只用于致命错误。
void g_warning( gchar *format, ... );
与上面的函数类似,在信息前面添加“ ** WARNING **:”,不退出应用程序。它可以用于不太严重的错误。
void g_message( gchar *format, ... );
在字符串前添加“message: ”,用于显示一条信息。
gchar *g_strsignal( gint signum );
打印给定信号号码的Linux系统信号的名称。在通用信号处理函数中很有用。
################################## 其他实用函数 ##################################
glib还提供了一系列实用函数,可以用于获取程序名称、当前目录、临时目录等。
这些函数都是在glib.h中定义的。
/* 返回应用程序的名称* /
gchar* g_get_prgname (void);
/* 设置应用程序的名称* /
void g_set_prgname (const gchar *prgname);
/* 返回当前用户的名称* /
gchar* g_get_user_name (void);
/* 返回用户的真实名称。该名称来自“passwd”文件。返回当前用户的主目录* /
gchar* g_get_real_name (void);
/* 返回当前使用的临时目录,它按环境变量TMPDIR、TMPandTEMP 的顺序查找。
如果上面的环境变量都没有定义,返回“ / t m p”* /
gchar* g_get_home_dir (void);
gchar* g_get_tmp_dir (void);
/* 返回当前目录。返回的字符串不再需要时应该用g_free ( ) 释放* /
gchar* g_get_current_dir (void);
/ *获得文件名的不带任何前导目录部分的名称。它返回一个指向给定文件名字符串的指针* /
gchar* g_basename (const gchar *file_name);
/* 返回文件名的目录部分。如果文件名不包含目录部分,返回“ .”。
* 返回的字符串不再使用时应该用g_free() 函数释放* /
gchar* g_dirname (const gchar *file_name);
/* 如果给定的file_name是绝对文件名(包含从根目录开始的完整路径,比如/usr/local),返回TRUE * /
gboolean g_path_is_absolute (const gchar *file_name);
/* 返回一个指向文件名的根部标志(“/”)之后部分的指针。
* 如果文件名file_name不是一个绝对路径,返回NULL * /
gchar* g_path_skip_root (gchar *file_name);
/ *指定一个在正常程序终止时要执行的函数* /
void g_atexit (GVoidFunc func);
上面介绍的只是glib库中的一小部分, glib的特性远远不止这些。如果想了解其它内容,参考glib.h文件。这里面的绝大多数函数都是简明易懂的。
另外,http://www.gtk.org上的glib文档也是极好的资源。
如果需要一些通用的函数但glib中还没有,考虑写一个glib风格的例程,将它贡献到glib库中!
本文总结自互联网,感谢原作者。