1. 程式人生 > >glib常用庫函式和一些定義

glib常用庫函式和一些定義

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 <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 %d/n", 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)

///////////////////////////////////////////////////////////////////////////////////
使用這些函式很簡單,下面的例子是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 <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:
   /* 無效列舉值* /
   g_assert_not_reached ( ) ;
   break ;
}

所有除錯巨集使用glib的g_log()輸出警告資訊,g_log()的警告資訊包含發生錯誤的應用程式或庫函式名字,並且還可以

使用一個替代的警告列印例程.

########################### 記憶體管理 ##############################

glib用自己的g_變體包裝了標準的malloc()和free(),即g_malloc()和g_free()。
它們有以下幾個小優點:
* g_malloc()總是返回gpointer,而不是char *,所以不必轉換返回值。
* 如果低層的malloc()失敗,g_malloc()將退出程式,所以不必檢查返回值是否是NULL。
* g_malloc() 對於分配0位元組返回NULL。
* g_free()忽略任何傳遞給它的NULL指標。

函式列表: glib記憶體分配
#include <glib.h>
gpointer g_malloc(gulong size)
void g_free(gpointer mem)
gpointer g_realloc(gpointer mem,gulong size)
gpointer g_memdup(gconstpointer mem,guint bytesize)

g_realloc()和realloc()是等價的。
g_malloc0(),它將分配的記憶體每一位都設定為0;
g_memdup()返回一個從mem開始的位元組數為bytesize的拷貝。
為了與g_malloc()一致,g_realloc()和g_malloc0()都可以分配0位元組記憶體。
g_memdup()在分配的原始記憶體中填充未設定的位,而不是設定為數值0。

巨集列表:記憶體分配巨集
#include <glib.h>
g_new(type, count)
g_new0(type, count)
g_renew(type, mem, count)

########################### 字串處理 ##############################

如果需要比gchar *更好的字串,glib提供了一個GString型別。
函式列表: 字串操作
#include <glib.h>
gint g_snprintf(gchar* buf,gulong n,const gchar* format,. . . )
gint g_strcasecmp(const gchar* s1,const gchar* s2)
gint g_strncasecmp(const gchar* s1,const gchar* s2,guint n)

在含有snprintf()的平臺上,g_snprintf()封裝了一個本地的snprintf(),並且比原有實現更穩定、安全。
以往的snprintf()不保證它所填充的緩衝是以NULL結束的,但g_snprintf()保證了這一點。
g_snprintf函式在buf引數中生成一個最大長度為n的字串。其中format是格式字串,“...”是要插入的引數。

函式列表: 修改字串
#include <glib.h>
void g_strdown(gchar* string)
void g_strup(gchar* string)
void g_strreverse(gchar* string)
gchar* g_strchug(gchar* string)
gchar* g_strchomp(gchar* string)
巨集g_strstrip()結合以上兩個函式,刪除字串前後的空格。

函式列表: 字串轉換
#include <glib.h>
gdouble g_strtod(const gchar* nptr,gchar** endptr)
gchar* g_strerror(gint errnum)
gchar* g_strsignal(gint signum)

函式列表: 分配字串
#include <glib.h>
gchar * g_strdup(const gchar* str)
gchar* g_strndup(const gchar* format,guint n)
gchar* g_strdup_printf(const gchar* format,. . . )
gchar* g_strdup_vprintf(const gchar* format,va_list args)
gchar* g_strescape(gchar* string)
gchar* g_strnfill(guint length,gchar fill_char)
/////////////////////////////////////////////////////////////////////////
gchar* str = g_malloc(256);
g_snprintf(str, 256, "%d printf-style %s", 1, "format");
用下面的程式碼,不需計算緩衝區的大小:
gchar* str = g_strdup_printf("%d printf-style %", 1, "format") ;
/////////////////////////////////////////////////////////////////////////

函式列表:連線字串的函式
#include <glib.h>
gchar* g_strconcat(const gchar* string1,. . . )
gchar* g_strjoin(const gchar* separator,. . . )

函式列表: 處理以NULL結尾的字串向量
#include <glib.h>
gchar** g_strsplit(const gchar* string,const gchar* delimiter,gint max_tokens)
gchar* g_strjoinv(const gchar* separator,gchar** str_array)
void g_strfreev(gchar** str_array)

########################### 資料結構 ##############################

連結串列~~~~~~~~~~

glib提供了普通的單向連結串列和雙向連結串列,分別是GSList 和GList。

建立連結串列、新增一個元素的程式碼:
GSList* list = NULL;
gchar* element = g_strdup("a string");
list = g_slist_append(list, element);
刪除上面新增的元素並清空連結串列:
list = g_slist_remove(list, element);
為了清除整個連結串列,可使用g_slist_free(),它會快速刪除所有的連結;
g_slist_free()只釋放連結串列的單元,它並不知道怎樣操作連結串列內容。

訪問連結串列的元素,可以直接訪問GSList結構:
gchar* my_data = list->data;
為了遍歷整個連結串列,可以如下操作:
GSList* tmp = list;
while (tmp != NULL)
{
   printf("List data: %p/n", tmp->data);
   tmp = g_slist_next(tmp);
}

/////////////////////////////////////////////////////////////////////////////
下面的程式碼可以用來有效地向連結串列中新增資料:
void efficient_append(GSList** list, GSList** list_end, gpointer data)
{
   g_return_if_fail(list != NULL);
   g_return_if_fail(list_end != NULL);
   if (*list == NULL)
   {
      g_assert(*list_end == NULL);
      *list = g_slist_append(*list, data);
      *list_end = *list;
   }
   else
   { 
      *list_end = g_slist_append(*list_end, data)->next;
   }
}

要使用這個函式,應該在其他地方儲存指向連結串列和連結串列尾的指標,並將地址傳遞給efficient_append ():
GSList* list = NULL;
GSList* list_end = NULL;
efficient_append(&list, &list_end, g_strdup("Foo"));
efficient_append(&list, &list_end, g_strdup("Bar"));
efficient_append(&list, &list_end, g_strdup("Baz"));
//////////////////////////////////////////////////////////////////////////////

函式列表:改變連結串列內容
#include <glib.h>
/* 向連結串列最後追加資料,應將修改過的連結串列賦給連結串列指標* /
GSList* g_slist_append(GSList* list,gpointer data)
/* 向連結串列最前面新增資料,應將修改過的連結串列賦給連結串列指標* /
GSList* g_slist_prepend(GSList* list,gpointer data)
/* 在連結串列的position位置向連結串列插入資料,應將修改過的連結串列賦給連結串列指標* /
GSList* g_slist_insert(GSList* list,gpointer data,gint position)
/ *刪除連結串列中的data元素,應將修改過的連結串列賦給連結串列指標* /
GSList* g_slist_remove(GSList* list,gpointer data)

訪問連結串列元素可以使用下面的函式列表中的函式。
這些函式都不改變連結串列的結構。
g_slist_foreach()對連結串列的每一項呼叫Gfunc函式。
Gfunc函式是像下面這樣定義的:
typedef void (*GFunc)(gpointer data, gpointer user_data);
在g_slist_foreach()中,Gfunc函式會對連結串列的每個list->data呼叫一次,將user_data傳遞到g_slist_foreach()函

數中。

////////////////////////////////////////////////////////////////////////////////
例如, 有一個字串連結串列,並且想建立一個類似的連結串列,讓每個字串做一些變換。
下面是相應的程式碼,使用了前面例子中的efficient_append()函式。
typedef struct _AppendContext AppendContext;
struct _AppendContext {
   GSList* list;
   GSList* list_end;
   const gchar* append;
} ;
static void append_foreach(gpointer data, gpointer user_data)
{
   AppendContext* ac = (AppendContext*) user_data;
   gchar* oldstring = (gchar*) data;
   efficient_append(&ac->list, &ac->list_end, g_strconcat(oldstring, ac->append, NULL));
}
GSList * copy_with_append(GSList* list_of_strings, const gchar* append)
{
   AppendContext ac;
   ac.list = NULL;
   ac.list_end = NULL;
   ac.append = append;
   g_slist_foreach(list_of_strings, append_foreach, &ac);
   return ac.list;
}

函式列表:訪問連結串列中的資料
#include <glib.h>
GSList* g_slist_find(GSList* list,gpointer data)
GSList* g_slist_nth(GSList* list,guint n)
gpointer g_slist_nth_data(GSList* list,guint n)
GSList* g_slist_last(GSList* list)
gint g_slist_index(GSList* list,gpointer data)
void g_slist_foreach(GSList* list,GFunc func,gpointer user_data)

函式列表: 操縱連結串列
#include <glib.h>
/* 返回連結串列的長度* /
guint g_slist_length(GSList* list)
/* 將list1和list2兩個連結串列連線成一個新連結串列* /
GSList* g_slist_concat(GSList* list1,GSList* list2)
/ *將連結串列的元素顛倒次序* /
GSList* g_slist_reverse(GSList* list)
/ *返回連結串列list的一個拷貝* /
GSList* g_slist_copy(GSList* list)

還有一些用於對連結串列排序的函式,見下面的函式列表。要使用這些函式,必須寫一個比較函式GcompareFunc,就像標準

C裡面的qsort()函式一樣。
在glib裡面,比較函式是這個樣子:
typedef gint (*GCompareFunc) (gconstpointer a, gconstpointer b);
如果a < b,函式應該返回一個負值;如果a > b,返回一個正值;如果a = b,返回0。

函式列表: 對連結串列排序
#include <glib.h>
GSList* g_slist_insert_sorted(GSList* list,gpointer data,GCompareFunc func)
GSList* g_slist_sort(GSList* list,GCompareFunc func)
GSList* g_slist_find_custom(GSList* list,gpointer data,GCompareFunc func)

樹~~~~~~~~~~~~~~

在glib中有兩種不同的樹:GTree是基本的平衡二叉樹,它將儲存按鍵值排序成對鍵值; GNode儲存任意的樹結構資料

,比如分析樹或分類樹。

函式列表:建立和銷燬平衡二叉樹
#include <glib.h>
GTree* g_tree_new(GCompareFunc key_compare_func)
void g_tree_destroy(GTree* tree)

函式列表: 操縱G t r e e資料
#include <glib.h>
void g_tree_insert(GTree* tree,gpointer key,gpointer value)
void g_tree_remove(GTree* tree,gpointer key)
gpointer g_tree_lookup(GTree* tree,gpointer key)

函式列表: 獲得G Tr e e的大小
#include <glib.h>
/ *獲得樹的節點數* /
gint g_tree_nnodes(GTree* tree)
/ *獲得樹的高度* /
gint g_tree_height(GTree* tree)

使用g_tree_traverse()函式可以遍歷整棵樹。
要使用它,需要一個GtraverseFunc遍歷函式,它用來給g_tree_trave rse()函式傳遞每一對鍵值對和資料引數。
只要GTraverseFunc返回FALSE,遍歷繼續;返回TRUE時,遍歷停止。
可以用GTraverseFunc函式按值搜尋整棵樹。
以下是GTraverseFunc的定義:
typedef gint (*GTraverseFunc)(gpointer key, gpointer value, gpointer data);
G Tr a v e r s e Ty p e是列舉型,它有四種可能的值。下面是它們在G t r e e中各自的意思:
* G_IN_ORDER (中序遍歷)首先遞迴左子樹節點(通過GCompareFunc比較後,較小的鍵),然後對當前節點的鍵值對呼叫

遍歷函式,最後遞迴右子樹。這種遍歷方法是根據使用GCompareFunc函式從最小到最大遍歷。
* G_PRE_ORDER (先序遍歷)對當前節點的鍵值對呼叫遍歷函式,然後遞迴左子樹,最後遞迴右子樹。
* G_POST_ORDER (後序遍歷)先遞迴左子樹,然後遞迴右子樹,最後對當前節點的鍵值對呼叫遍歷函式。
* G_LEVEL_ORDER (水平遍歷)在GTree中不允許使用,只能用在Gnode中。

函式列表: 遍歷GTree
#include <glib.h>
void g_tree_traverse( GTree* tree,
                      GTraverseFunc traverse_func,
                      GTraverseType traverse_type,
                      gpointer data )

一個GNode是一棵N維的樹,由雙鏈表(父和子連結串列)實現。
這樣,大多數連結串列操作函式在Gnode API中都有對等的函式。可以用多種方式遍歷。

以下是一個GNode的宣告:
typedef struct _GNode GNode;
struct _GNode
{
   gpointer data;
   GNode *next;
   GNode *prev;
   GNode *parent;
   GNode *children;
} ;

巨集列表:訪問GNode成員
#include <glib.h>
/ *返回GNode的前一個節點* /
g_node_prev_sibling ( node )
/ *返回GNode的下一個節點* /
g_node_next_sibling ( node )
/ *返回GNode的第一個子節點* /
g_node_first_child( node )

用g_node_new ()函式建立一個新節點。
g_node_new ()建立一個包含資料,並且無子節點、無父節點的Gnode節點。
通常僅用g_node_new ()建立根節點,還有一些巨集可以根據需要自動建立新節點。
函式列表: 建立一個GNode
#include <glib.h>
GNode* g_node_new(gpointer data)

函式列表: 建立一棵GNode樹
#include <glib.h>
/ *在父節點p a r e n t的p o s i t i o n處插入節點n o d e * /
GNode* g_node_insert(GNode* parent,gint position,GNode* node)
/ *在父節點p a r e n t中的s i b l i n g節點之前插入節點n o d e * /
GNode* g_node_insert_before(GNode* parent,GNode* sibling,GNode* node)
/ *在父節點p a r e n t最前面插入節點n o d e * /
GNode* g_node_prepend(GNode* parent,GNode* node)

巨集列表:向Gnode新增、插入資料
#include <glib.h>
g_node_append(parent, node)
g_node_insert_data(parent, position, data)
g_node_insert_data_before(parent, sibling, data)
g_node_prepend_data(parent, data)
g_node_append_data(parent, data)

函式列表: 銷燬GNode
#include <glib.h>
void g_node_destroy(GNode* root)
void g_node_unlink(GNode* node)

巨集列表:判斷G n o d e的型別
#include <glib.h>
G_NODE_IS_ROOT ( node )
G_NODE_IS_LEAF ( node )

下面函式列表中的函式返回Gnode的一些有用資訊,包括它的節點數、根節點、深度以及含有特定資料指標的節點。
其中的遍歷型別GtraverseType在Gtree中介紹過。
下面是在Gnode中它的可能取值:
* G_IN_ORDER 先遞迴節點最左邊的子樹,並訪問節點本身,然後遞迴節點子樹的其他部分。
  這不是很有用,因為多數情況用於Gtree中。
* G_PRE_ORDER 訪問當前節點,然後遞迴每一個子樹。
* G_POST_ORDER 按序遞迴每個子樹,然後訪問當前節點。
* G_LEVEL_ORDER 首先訪問節點本身,然後每個子樹,然後子樹的子樹,然後子樹的子樹的子樹,以次類推。
  也就是說,它先訪問深度為0的節點,然後是深度為1,然後是深度為2,等等。
GNode的樹遍歷函式有一個GTraverseFlags引數。這是一個位域,用來改變遍歷的種類。
當前僅有三個標誌—只訪問葉節點,非葉節點,或者所有節點:
* G_TRAVERSE_LEAFS 指僅遍歷葉節點。
* G_TRAVERSE_NON_LEAFS 指僅遍歷非葉節點。
* G_TRAVERSE_ALL 只是指( G_TRAVERSE_LEAFS | G_TRAVERSE_NON_LEAFS )快捷方式。

函式列表: 取得G N o d e屬性
#include <glib.h>
guint g_node_n_nodes(GNode* root,GTraverseFlags flags)
GNode* g_node_get_root(GNode* node)
Gboolean g_node_is_ancestor(GNode* node,GNode* descendant)
Guint g_node_depth(GNode* node)
GNode* g_node_find(GNode* root,GTraverseType order,GTraverseFlags flags,gpointer data)

GNode有兩個獨有的函式型別定義:
typedef gboolean (*GNodeTraverseFunc) (GNode* node, gpointer data);
typedef void (*GNodeForeachFunc) (GNode* node, gpointer data);
這些函式呼叫以要訪問的節點指標以及使用者資料作為引數。GNodeTraverseFunc返回TRUE,停止任何正在進行的遍歷,

這樣就能將GnodeTraverseFunc與g_node_traverse()結合起來按值搜尋樹。

函式列表: 訪問GNode
#include <glib.h>
/ *對Gnode進行遍歷* /
void g_node_traverse( GNode* root,
                      GTraverseType order,
                      GTraverseFlags flags,
                      gint max_depth,
                      GNodeTraverseFunc func,
                      gpointer data )
/ *返回GNode的最大高度* /
guint g_node_max_height(GNode* root)
/ *對Gnode的每個子節點呼叫一次f u n c函式* /
void g_node_children_foreach( GNode* node,
                              GTraverseFlags flags,
                              GNodeForeachFunc func,
                              gpointer data )
/ *顛倒node的子節點順序* /
void g_node_reverse_children(GNode* node)
/ *返回節點node的子節點個數* /
guint g_node_n_children(GNode* node)
/ *返回node的第n個子節點* /
GNode* g_node_nth_child(GNode* node,guint n)
/ *返回node的最後一個子節點* /
GNode* g_node_last_child(GNode* node)
/ *在node中查詢值為d a t e的節點* /
GNode* g_node_find_child(GNode* node,GTraverseFlags flags,gpointer data)
/ *返回子節點child在node中的位置* /
gint g_node_child_position(GNode* node,GNode* child)
/ *返回資料data在node中的索引號* /
gint g_node_child_index(GNode* node,gpointer data)
/ *以子節點形式返回node的第一個兄弟節點* /
GNode* g_node_first_sibling(GNode* node)
/ *以子節點形式返回node的第一個兄弟節點* /
GNode* g_node_last_sibling(GNode* node)

雜湊表~~~~~~~~~~`

GHashTable是一個簡單的雜湊表實現,提供一個帶有連續時間查尋的關聯陣列。
要使用雜湊表,必須提供一個GhashFunc函式,當向它傳遞一個雜湊值時,會返回正整數:
typedef guint (*GHashFunc) (gconstpointer key);
除了GhashFunc,還需要一個GcompareFunc比較函式用來測試關鍵字是否相等。
不過,雖然GCompareFunc函式原型是一樣的,但它在GHashTable中的用法和在GSList、Gtree中的用法不一樣。
在GHashTable中可以將GcompareFunc看作是等式操作符,如果引數是相等的,則返回TRUE。

函式列表: GHashTable
#include <glib.h>
GHashTable* g_hash_table_new(GHashFunc hash_func,GCompareFunc key_compare_func)
void g_hash_table_destroy(GHashTable* hash_table)

函式列表: 雜湊表/比較函式
#include <glib.h>
guint g_int_hash(gconstpointer v)
gint g_int_equal(gconstpointer v1,gconstpointer v2)
guint g_direct_hash(gconstpointer v)
gint g_direct_equal(gconstpointer v1,gconstpointer v2)
guint g_str_hash(gconstpointer v)
gint g_str_equal(gconstpointer v1,gconstpointer v2)

函式列表: 處理GHashTable
#include <glib.h>
void g_hash_table_insert(GHashTable* hash_table,gpointer key,gpointer value)
void g_hash_table_remove(GHashTable * hash_table,gconstpointer key)
gpointer g_hash_table_lookup(GHashTable * hash_table,gconstpointer key)
gboolean g_hash_table_lookup_extended( GHashTable* hash_table,
                                       gconstpointer lookup_key,
                                       gpointer* orig_key,
                                       gpointer* value )

函式列表: 凍結和解凍GHashTable
#include <glib.h>
/ * *凍結雜湊表/
void g_hash_table_freeze(GHashTable* hash_table)
/ *將雜湊表解凍* /
void g_hash_table_thaw(GHashTable* hash_table)


####################################### GString #####################################

GString的定義:
struct GString
{
    gchar *str; /* Points to the st’rsi ncgurrent /0-terminated value. */
    gint len; /* Current length */
} ;

用下面的函式建立新的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檔案。這裡面的絕大多數函式都是簡明易懂的。
另外,http://www.gtk.org上的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中而來.