包括存储块、双向链表、单向链表、哈希表、动态列表、关系和元组及缓存。最后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
计时器函数可用于记录操作记时,也可以记录程序的间断运行时间。
编程中经常需要对字符串进行拼接、截取、大小写转换,原本在C中这些操作是非常繁琐的。现在GLib定义了一个叫做GString的新类型,它可以自动增长,并且提供了
一系列方便的操作函数。
struct GString{
gchar *str;/*指向当前以\0结尾的字符串*/
gint len;/*当前字符长度*/
}
六、错误处理
除了上述之外,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.....