Honesty and diligence should be your eternal mates.
分类: LINUX
2011-09-04 21:56:40
原文地址:http://dev.csdn.net/Develop/article/28/74068.shtm
glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性。
glib是Gtk +库和Gnome的基础。glib可以在多个平台下使用,比如Linux、Unix、Windows等。glib为许多标准的、常用的C语言结构提供了相应的替代物。
使用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
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 %d\n", GPOINTER_TO_INT(my_pointer));
//////////////////////////////////////////////////////////////
这些宏允许在一个指针中存储一个整数,但在一个整数中存储一个指针是不行的。
如果要实现的话,必须在一个长整型中存储指针。
宏列表:
在指针中存储整数的宏
#include
GINT_TO_POINTER ( p )
GPOINTER_TO_INT ( p )
GUINT_TO_POINTER ( p )
GPOINTER_TO_UINT ( p )
调试宏:
定义了G_DISABLE_CHECKS或G_DISABLE_ASSERT之后,编译时它们就会消失.
宏列表:
前提条件检查
#include
g_return_if_fail ( condition )
g_return_val_if_fail(condition, retval)
///////////////////////////////////////////////////////////////////////////////////
使用这些函数很简单,下面的例子是g l i b中哈希表的实现:
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
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:%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: ”,用于显示一条信息。
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文件。这里面的绝大多数函数都是简明易懂的。
另外,上的glib文档也是极好的资源。
如果你需要一些通用的函数,但glib中还没有,考虑写一个glib风格的例程,将它贡献到glib库中!
你自己,以及全世界的glib使用者,都将因为你的出色工作而受益。
glib提供许多有用的函数及定义. 我把它们列在这里并做简短的解释. 很多都是与libc重复, 对这些我不再详述. 这些大致上是用来参考, 您知道有什麽东西可以用就好.
17.1 定义
为保持资料型态的一致, 这里有一些定义:
G_MINFLOAT
G_MAXFLOAT
G_MINDOUBLE
G_MAXDOUBLE
G_MINSHORT
G_MAXSHORT
G_MININT
G_MAXINT
G_MINLONG
G_MAXLONG
此外, 以下的typedefs. 没有列出来的是会变的, 要看是在那一种平台上. 如果您想要具有可移植性, 记得避免去使用sizeof(pointer). 例如, 一个指标在Alpha上是8 bytes, 但在Inter上为4 bytes.
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
17.2 双向链结串列
以下函数用来产生, 管理及销毁双向链结串列.
GList* g_list_alloc (void);
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
GList* g_list_append (GList *list,
gpointer data);
GList* g_list_prepend (GList *list,
gpointer data);
GList* g_list_insert (GList *list,
gpointer data,
gint position);
GList* g_list_remove (GList *list,
gpointer data);
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);
17.3 单向链结串列
以下函数是用来管理单向链结串列:
GSList* g_slist_alloc (void);
void g_slist_free (GSList *list);
void g_slist_free_1 (GSList *list);
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);
17.4 记忆体管理
gpointer g_malloc (gulong size);
这是替代malloc()用的. 你不需要去检查返回值, 因为它已经帮你做好了, 保证.
gpointer g_malloc0 (gulong size);
一样, 不过会在返回之前将记忆体归零.
gpointer g_realloc (gpointer mem,
gulong size);
重定记忆体大小.
void g_free (gpointer mem);
void g_mem_profile (void);
将记忆体的使用状况写到一个档案, 不过您必须要在glib/gmem.c里面, 加#define MEM_PROFILE, 然後重新编译.
void g_mem_check (gpointer mem);
检查记忆体位置是否有效. 您必须要在glib/gmem.c上加#define MEM_CHECK, 然後重新编译.
17.5 Timers
Timer函数..
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);
17.6 字串处理
GString* g_string_new (gchar *init);
void g_string_free (GString *string,
gint free_segment);
GString* g_string_assign (GString *lval,
gchar *rval);
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,
...);
17.7 工具及除错函数
gchar* g_strdup (const gchar *str);
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);
列印Unix系统的信号名称, 在信号处理时很有用.
这些大都从glib.h中而来.