GLib是一種底層庫,創建GDK和GTK應用程序時該庫提供許多有用的定義和函數。
包括基本類型及限制的定義、標準宏、類型轉化、字節序、存儲分配、警告和斷言、消息記錄、計時器、字符串工具、hook函數、句法掃描器、動態加載模塊和字符串自動補全,同時也提供了許多數據類型及相關操作。
包括存儲塊、雙向鏈表、單向鏈表、哈希表、動態列表、關系和元組及緩存。最后GLib具有很好的移植性,所以使用GLib作為底層應用支持,那么也保證了應用的可移植性。
類型定義:
1. 整數類型:gint8、guint8、gint16、guint16、gint32、guint32、gint64、guint64。不是所有的平臺都提供64位整型
2. 整數類型gshort、glong、gint和short、long、int相同
3. 布爾類型gboolean:gboolean可以取兩個值:TRUE和FALSE
4. 字符型gchar和char相同
5. 浮點型gfloat和gdouble和float、double完全等價
6. 指針gpointer對應于標準C的void*
7. gconstpointer對于于標準C的const void*
?
glib宏:
整型與指針類型間的轉換
1. GINT_TO_POINTER(a):將int型轉換成gpointer類型
2. GPOINTER_TO_INT(a):將gpointer類型轉換成int型
3. GUINT_TO_POINTER(a):將uint類型轉換成gpointer類型
4. GPOINTER_TO_UINT(a):將gpointer類型轉換成整型
5. NULL宏的定義:#define NULL (void*)0(也就是說:0是一個整型數據,而NULL則是指針類型)
一、雙向鏈表
雙向鏈表中每個元素都包含一塊數據和指向前后元素的指針。這使得鏈表的雙向移動變的容易。
存儲的數據類型是gpointer,在GLib中,gpointer指向實際數據的指針。
不存在用于創建鏈表的函數,而是簡單的創建一個Glist* 變量,并設置它為NULL。
雙向鏈表中提供的Glib函數:
- 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):從鏈表中移除一個具有值data的元素,如果元素不存在,則鏈表不變????
- GList?*g_list_free(GList?*list):數釋放由GList使用的所有存儲區????
- 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):在鏈表中查找一個含有指定值的元素,沒有則返回NULL????
- 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?data):遍歷鏈表????
- gint?g_list_index(GList?*list,?gconstpointer?data):返回指定元素在鏈表中的位置,沒有找到匹配的元素,則返回-1。元素位置從0開始計算。??
- #include?<stdio.h>??
- #include?<stdlib.h>??
- #include?<glib.h>??
- #include?<string.h>??
- ??
- ??
- typedef?struct?_Teacher??
- {??
- ????gint?age;??
- ????gchar?*name;??
- }Teacher;??
- ??
- ??
- ??
- void?each_callback(gpointer?data,?gpointer?user_data)??
- {??
- ????Teacher?*t?=?(Teacher?*)data;??
- ????g_print("t->name?=?%s,?user?param:%s\n",?t->name,?(char?*)user_data);??
- }????
- ??
- ???
- int?main(?int?argc,char?*argv[]?)??
- {????
- ????GList?*list?=?NULL;??
- ????Teacher?*pTeacher1?=?g_new0(Teacher,1);??
- ????pTeacher1->name?=?g_new0(char,128);??
- ????strcpy(pTeacher1->name,"tiny?Jason");??
- ????list?=?g_list_append(list,?pTeacher1);??
- ??????
- ????Teacher?*pTeacher2?=?g_new0(Teacher,1);??
- ????pTeacher2->name?=?g_new0(char,128);??
- ????strcpy(pTeacher2->name,"Rorash");??
- ????list?=?g_list_prepend(list,?pTeacher2);????
- ??
- ??
- ????Teacher?*pTeacher3?=?g_new0(Teacher,1);??
- ????pTeacher3->name?=?g_new0(char,128);??
- ????strcpy(pTeacher3->name,"alibaba");??
- ????list?=?g_list_prepend(list,?pTeacher3);???
- ??????
- ????g_list_foreach(list,?each_callback,?"user_data");????
- ??
- ????GList?*second?=?g_list_find(list,?pTeacher2);??
- ????if(second?!=?NULL)??
- ????{??
- ????????Teacher*?t?=?(Teacher*)second->data;??
- ????????g_print("name?:%s\n",t->name);??
- ????}??
- ??
- ??
- ????list?=?g_list_remove(list,?pTeacher2);??
- ??????
- ????g_list_foreach(list,?each_callback,?"user_data");????
- ????
- ????gint?len?=?g_list_length(list);??
- ????g_print("len?:%d\n",len);??
- ??????
- ????GList?*nNode?=?g_list_nth(list,1);??
- ????if(nNode?!=?NULL)??
- ????{??
- ????????Teacher*?t?=?(Teacher*)nNode->data;??
- ????????g_print("name?:%s\n",t->name);??
- ????}??
- ??????
- ????g_list_free(list);??
- ?????
- ??return?0;????
- }????
makefile:
- .SUFFIXES:.c?.o??
- ??
- CC=gcc??
- SRCS=test_glib.c??
- OBJS=$(SRCS:.c=.o)??
- EXEC=test_glib??
- ??
- all:$(OBJS)??
- ????????$(CC)?-o?$(EXEC)?$(OBJS)?`pkg-config?--libs?glib-2.0`??
- ??
- .c.o:??
- ????????$(CC)?-o?$@?-c?-g?$<?`pkg-config?--cflags?glib-2.0`??
- clean:??
- ????????rm?-f?$(OBJS)??
運行結果:
- t->name?=?alibaba,?user?param:user_data??
- t->name?=?Rorash,?user?param:user_data??
- t->name?=?tiny?Jason,?user?param:user_data??
- name?:Rorash??
- t->name?=?alibaba,?user?param:user_data??
- t->name?=?tiny?Jason,?user?param:user_data??
- len?:2??
- name?:tiny?Jason??
二、單向鏈表
- 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):鏈表中刪除具有值data的元素??
- GSList?*g_slist_reverse(GSList?*list):反轉元素位置??
- GSList?*g_slist_nth(GSList?*list,?gint?n):返回鏈表中下一個元素??
- GSList?*g_slist_find(GSList?*list,?gpointer?data):查找指定data的元素,沒有則返回NULL??
- GSList?*g_slist_last(GSList?*list):查找鏈表的最后一個元素??
- gint?g_slist_length(GSList?*list):返回鏈表元素個數??
- void?g_slist_foreach(GSList?*list,?GFunc?func,?gpointer?data):遍歷鏈表??
三、存儲管理
- gpointer?g_malloc(gulong?size):這是malloc的替代函數,不需要檢查返回值。如果存儲分配因任何原因失敗,則應用程序終止。??
- gpointer?g_malloc0(gulong?size):和g_malloc具有相同功能,但在返回指向分配存儲塊的指針前,將該存儲塊清0。??
- gpointer?g_realloc(gpointer?mem,?gulong?size):重新分配由mem開始的指針,并設置大小為size字節。??
- void?g_free(gpointer?mem):釋放分配的存儲塊。如果mem為NULL,則直接返回。??
四、計時器
計時器函數可用于記錄操作記時,也可以記錄程序的間斷運行時間。
- 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):重置計時器??
- void?g_timer_continue(GTimer?*timer):繼續計時??
- gdobule?g_timer_elapsed(GTimer?*timer,?gulong?*microseconds):決定所耗時間??
Example:
- GTimer?*timer;??
- ??
- void?each_callback(gpointer?data,?gpointer?user_data)??
- {??
- ????g_print("element:%s,?user?param:%s\n",?(gchar*)data,?(gchar*)user_data);??
- }??
- ??
- int?main(?int?argc,??
- ??????????char?*argv[]?)??
- {??
- ??GList?*list?=?NULL;??
- ??gulong?seconds;??
- ??int?i=0;??
- ??timer?=?g_timer_new();??
- ??
- ??list?=?g_list_append(list,?"second");??
- ??list?=?g_list_prepend(list,?"first");??
- ??
- ??g_timer_start(timer);??
- ??g_list_foreach(list,?each_callback,?"user_data");??
- ??g_timer_stop(timer);??
- ??
- ??g_timer_elapsed(timer,?&seconds);??
- ??
- ??g_print("use?seconds:%ld\n",?seconds);??
- ??
- ??g_timer_continue(timer);??
- ??
- ??for(i;?i<=1000;?i++)??
- ??{??
- ??????g_print("%d",?i);??
- ??}??
- ??g_timer_elapsed(timer,?&seconds);??
- ??g_print("use?seconds:%ld\n",?seconds);??
- ??return?0;??
- }??
五、字符串處理
編程中經常需要對字符串進行拼接、截取、大小寫轉換,原本在C中這些操作是非常繁瑣的。現在GLib定義了一個叫做GString的新類型,它可以自動增長,并且提供了
一系列方便的操作函數。
struct GString{
gchar *str;/*指向當前以\0結尾的字符串*/
gint len;/*當前字符長度*/
}
- GString?*g_string_new(gchar?*init):創建GList類型??
- 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,?...):格式化字符串??
- gchar?*g_strdup?(const?gchar?*str):復制字符串,返回一個新分配的字符串。??
- gchar?*g_strndup(const?gchar?*str,?gsize?n):復制指定個數的字符串,返回新分配的字符串??
- gchar?*g_strstr_len(const?gchar?*haystack,?gssize?haystack_len,?const?gchar?*needle):在限定長度內,第一次出現指定字符的指針??
- gchar?*g_strrstr(const?gchar?*haystrack,?const?gchar?*needle):搜索字符串haystack中最后一次出現的串針。??
- gchar?*g_strrstr_len(const?gchar?*haystrack,?gssize?haystrack_len,?const?gchar?*needle)??
- gboolean?g_str_hash_prefix(const?gchar?*str,?const?gchar?*prefix):返回字符串是否以某個前綴開頭??
- int?g_strcmp0(const?char?*str1,?const?char?*str2):對比兩個字符串??
- gchar?**g_strsplit(const?gchar?*string,?const?gchar?*delimiter,?gint?max_tokens):分割字符串,保存為數組??
- gchar?*g_strconcat(const?gchar?*string1,?...):字符串拼接??
- gchar?*g_strjoin(const?gchar?*separator,?...):以某個字符串隔離并拼接??
更多
http://gtk-doc-cn.googlecode.com/svn/docs/glib/glib-String-Utility-Functions.html#g-strdup
六、錯誤處理
- gchar?*g_strdup(?const?gchar?*str?):替代strdup函數。把原字符串內容復制到新分配的存儲塊中,返回指向它的指針。??
- gchar?*g_strerror(?gint?errnum?);??
- void?g_error(?gchar?*format,?...?);錯誤提示:“?**?ERROR?**?”并且退出程序。僅用在致命錯誤上。??
- void?g_warning(?gchar?*format,?...?):錯誤提示:“?**?WARNING?**?”??
- void?g_message(?gchar?*format,?...?):在傳遞字符串前打印"message"??
- void?g_print(?gchar?*format,?...?):替代printf函數??
除了上述之外,GLib還提供了很多功能,包括編碼轉換、正則、XMP解析、Test框架等等。
glib about thread,mutex,cond
- #include?<glib.h>??
- #include?<stdio.h>??
- ??
- static?int?num?=?0;??
- GMutex?mutex;??
- GCond?cond;??
- ??
- gboolean?_thread_main1(void?*data)??
- {??
- ????while(1)??
- ????{??
- ??????????g_mutex_lock(&mutex);??
- ????????while(num?<=?0)??
- ????????{??
- ????????????g_printf("consumer[%d]?is?wating.....\n",(int)data);??
- ????????????g_cond_wait(&cond,?&mutex?);??
- ????????????g_printf("consumer[%d]?wake?up.....\n",(int)data);??
- ????????}??
- ????????g_printf("consmuer[%d]?before,num?=?%d.....\n",(int)data,num);??
- ????????num--;??
- ????????g_printf("consmuer[%d]?after,num?=?%d.....\n",(int)data,num);??
- ????????g_mutex_unlock(&mutex);??
- ????????sleep(1);??
- ????}??
- ????return?TRUE;??
- }??
- ??
- ??
- gboolean?_thread_main2(void?*data)??
- {??
- ????while(1)??
- ????{??
- ??????????g_mutex_lock(&mutex);??
- ????????num++;??
- ????????if(num?>?0)??
- ????????{??
- ????????????g_printf("prepare?to?sigal...please?wait?for?5?seconds\n");??
- ????????????sleep(5);??
- ????????????g_cond_signal(&cond);??
- ????????????g_printf("after?g_cond_signal\n");??
- ????????}??
- ????????g_mutex_unlock(&mutex);??
- ????????sleep(2);??
- ????}??
- ????return?TRUE;??
- }??
- ??
- ??
- int?main(?int?argc,char?*argv[]?)??
- {????
- ????GThread?*consumer1?=?NULL;??
- ????GThread?*consumer2?=?NULL;??
- ????GThread?*consumer3?=?NULL;??
- ??????
- ????GThread?*thread2?=?NULL;??
- ??????
- ??????
- ????g_mutex_init(&mutex);??
- ????g_cond_init(?&cond?);??
- ??????
- ????consumer1?=?g_thread_new("consumer1",?(GThreadFunc)_thread_main1,?(void*)1);??
- ????consumer2?=?g_thread_new("consumer2",?(GThreadFunc)_thread_main1,?(void*)2);??
- ????consumer3?=?g_thread_new("consumer3",?(GThreadFunc)_thread_main1,?(void*)3);??
- ??????
- ????thread2?=?g_thread_new("thread2",?(GThreadFunc)_thread_main2,?NULL);??
- ??????
- ??????
- ????g_thread_join?(consumer1);??
- ????g_thread_join?(consumer2);??
- ????g_thread_join?(consumer3);??
- ??????
- ??????
- ????g_thread_join?(thread2);??
- ????return?0;????
- }????
- ?????
結果:
consumer[1] is wating.....
consumer[2] is wating.....
prepare to sigal...please wait for 5 seconds
after g_cond_signal
consumer[1] wake up.....
consmuer[1] before,num = 1.....
consmuer[1] after,num = 0.....
consumer[3] is wating.....
consumer[1] is wating.....
prepare to sigal...please wait for 5 seconds
after g_cond_signal
consumer[2] wake up.....
consmuer[2] before,num = 1.....
consmuer[2] after,num = 0.....
consumer[2] is wating.....
prepare to sigal...please wait for 5 seconds
after g_cond_signal
consumer[3] wake up.....
consmuer[3] before,num = 1.....
consmuer[3] after,num = 0.....
consumer[3] is wating.....
prepare to sigal...please wait for 5 seconds
after g_cond_signal
consumer[1] wake up.....
consmuer[1] before,num = 1.....
consmuer[1] after,num = 0.....
consumer[1] is wating.....
prepare to sigal...please wait for 5 seconds
after g_cond_signal
consumer[2] wake up.....
consmuer[2] before,num = 1.....
consmuer[2] after,num = 0.....
consumer[2] is wating.....