Glib介绍

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函数:

[cpp] view plaincopy
  1. GList *g_list_append(GList *list, gpointer data):将一个新元素加入到链表尾    
  2. GList *g_list_prepend(GList *list, gpointer data):将一个新元素加入到链表头    
  3. GList *g_list_insert(GList *list, gpointer data, gint position):插入一个新元素到链表的指定位置    
  4. GList *g_list_remove(GList *list, gpointer data):从链表中移除一个具有值data的元素,如果元素不存在,则链表不变    
  5. GList *g_list_free(GList *list):数释放由GList使用的所有存储区    
  6. GList *g_list_remove_link(GList *list, GList *link)    
  7. GList *g_list_reverse(GList *list):链表元素位置反转    
  8. GList *g_list_nth(GList *list, gint n):获取指定位置元素    
  9. GList *g_list_find(GList *list, gpointer data):在链表中查找一个含有指定值的元素,没有则返回NULL    
  10. GList *g_list_last(GList *list):获取链表中最后一个元素    
  11. GList *g_list_first(GList *list):获取链表中第一个元素    
  12. gint g_list_length(GList *list):返回链表元素个数    
  13. void g_list_foreach(GList *list, GFunc func, gpointer data):遍历链表    
  14. gint g_list_index(GList *list, gconstpointer data):返回指定元素在链表中的位置,没有找到匹配的元素,则返回-1。元素位置从0开始计算。  

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <glib.h>  
  4. #include <string.h>  
  5.   
  6.   
  7. typedef struct _Teacher  
  8. {  
  9.     gint age;  
  10.     gchar *name;  
  11. }Teacher;  
  12.   
  13.   
  14.   
  15. void each_callback(gpointer data, gpointer user_data)  
  16. {  
  17.     Teacher *t = (Teacher *)data;  
  18.     g_print("t->name = %s, user param:%s\n", t->name, (char *)user_data);  
  19. }    
  20.   
  21.    
  22. int main( int argc,char *argv[] )  
  23. {    
  24.     GList *list = NULL;  
  25.     Teacher *pTeacher1 = g_new0(Teacher,1);  
  26.     pTeacher1->name = g_new0(char,128);  
  27.     strcpy(pTeacher1->name,"tiny Jason");  
  28.     list = g_list_append(list, pTeacher1);  
  29.       
  30.     Teacher *pTeacher2 = g_new0(Teacher,1);  
  31.     pTeacher2->name = g_new0(char,128);  
  32.     strcpy(pTeacher2->name,"Rorash");  
  33.     list = g_list_prepend(list, pTeacher2);    
  34.   
  35.   
  36.     Teacher *pTeacher3 = g_new0(Teacher,1);  
  37.     pTeacher3->name = g_new0(char,128);  
  38.     strcpy(pTeacher3->name,"alibaba");  
  39.     list = g_list_prepend(list, pTeacher3);   
  40.       
  41.     g_list_foreach(list, each_callback, "user_data");    
  42.   
  43.     GList *second = g_list_find(list, pTeacher2);  
  44.     if(second != NULL)  
  45.     {  
  46.         Teacher* t = (Teacher*)second->data;  
  47.         g_print("name :%s\n",t->name);  
  48.     }  
  49.   
  50.   
  51.     list = g_list_remove(list, pTeacher2);  
  52.       
  53.     g_list_foreach(list, each_callback, "user_data");    
  54.     
  55.     gint len = g_list_length(list);  
  56.     g_print("len :%d\n",len);  
  57.       
  58.     GList *nNode = g_list_nth(list,1);  
  59.     if(nNode != NULL)  
  60.     {  
  61.         Teacher* t = (Teacher*)nNode->data;  
  62.         g_print("name :%s\n",t->name);  
  63.     }  
  64.       
  65.     g_list_free(list);  
  66.      
  67.   return 0;    
  68. }    

makefile:

[cpp] view plaincopy
  1. .SUFFIXES:.c .o  
  2.   
  3. CC=gcc  
  4. SRCS=test_glib.c  
  5. OBJS=$(SRCS:.c=.o)  
  6. EXEC=test_glib  
  7.   
  8. all:$(OBJS)  
  9.         $(CC) -o $(EXEC) $(OBJS) `pkg-config --libs glib-2.0`  
  10.   
  11. .c.o:  
  12.         $(CC) -o $@ -c -g $< `pkg-config --cflags glib-2.0`  
  13. clean:  
  14.         rm -f $(OBJS)  



运行结果:

[cpp] view plaincopy
  1. t->name = alibaba, user param:user_data  
  2. t->name = Rorash, user param:user_data  
  3. t->name = tiny Jason, user param:user_data  
  4. name :Rorash  
  5. t->name = alibaba, user param:user_data  
  6. t->name = tiny Jason, user param:user_data  
  7. len :2  
  8. name :tiny Jason  



二、单向链表
[cpp] view plain copy
  1. GSList *g_slist_append(GSList *list, gpointer data):链表最后新增一个元素  
  2. GSList *g_slist_prepend(GSList *list, gpointer data):链表最前面新增一个元素  
  3. GSList *g_slist_insert(GSList *list, gpointer data, gint position):指定链表位置插入新元素  
  4. GSList *g_slist_remove(GSList *list, gpointer data):链表中删除具有值data的元素  
  5. GSList *g_slist_reverse(GSList *list):反转元素位置  
  6. GSList *g_slist_nth(GSList *list, gint n):返回链表中下一个元素  
  7. GSList *g_slist_find(GSList *list, gpointer data):查找指定data的元素,没有则返回NULL  
  8. GSList *g_slist_last(GSList *list):查找链表的最后一个元素  
  9. gint g_slist_length(GSList *list):返回链表元素个数  
  10. void g_slist_foreach(GSList *list, GFunc func, gpointer data):遍历链表  

三、存储管理
[cpp] view plain copy
  1. gpointer g_malloc(gulong size):这是malloc的替代函数,不需要检查返回值。如果存储分配因任何原因失败,则应用程序终止。  
  2. gpointer g_malloc0(gulong size):和g_malloc具有相同功能,但在返回指向分配存储块的指针前,将该存储块清0。  
  3. gpointer g_realloc(gpointer mem, gulong size):重新分配由mem开始的指针,并设置大小为size字节。  
  4. void g_free(gpointer mem):释放分配的存储块。如果mem为NULL,则直接返回。  

四、计时器

计时器函数可用于记录操作记时,也可以记录程序的间断运行时间。

[cpp] view plain copy
  1. GTimer *g_timer_new(void):创建一个新计时器  
  2. void g_timer_destroy(GTimer *timer):注销计时器  
  3. void g_timer_start(GTimer *timer):计时器开始  
  4. void g_timer_stop(GTimer *timer):停止计时  
  5. void g_timer_reset(GTimer *timer):重置计时器  
  6. void g_timer_continue(GTimer *timer):继续计时  
  7. gdobule g_timer_elapsed(GTimer *timer, gulong *microseconds):决定所耗时间  

Example:
[cpp] view plain copy
  1. GTimer *timer;  
  2.   
  3. void each_callback(gpointer data, gpointer user_data)  
  4. {  
  5.     g_print("element:%s, user param:%s\n", (gchar*)data, (gchar*)user_data);  
  6. }  
  7.   
  8. int main( int argc,  
  9.           char *argv[] )  
  10. {  
  11.   GList *list = NULL;  
  12.   gulong seconds;  
  13.   int i=0;  
  14.   timer = g_timer_new();  
  15.   
  16.   list = g_list_append(list, "second");  
  17.   list = g_list_prepend(list, "first");  
  18.   
  19.   g_timer_start(timer);  
  20.   g_list_foreach(list, each_callback, "user_data");  
  21.   g_timer_stop(timer);  
  22.   
  23.   g_timer_elapsed(timer, &seconds);  
  24.   
  25.   g_print("use seconds:%ld\n", seconds);  
  26.   
  27.   g_timer_continue(timer);  
  28.   
  29.   for(i; i<=1000; i++)  
  30.   {  
  31.       g_print("%d", i);  
  32.   }  
  33.   g_timer_elapsed(timer, &seconds);  
  34.   g_print("use seconds:%ld\n", seconds);  
  35.   return 0;  
  36. }  

五、字符串处理

编程中经常需要对字符串进行拼接、截取、大小写转换,原本在C中这些操作是非常繁琐的。现在GLib定义了一个叫做GString的新类型,它可以自动增长,并且提供了
一系列方便的操作函数。
struct GString{
gchar *str;/*指向当前以\0结尾的字符串*/
gint len;/*当前字符长度*/
}

[cpp] view plain copy
  1. GString *g_string_new(gchar *init):创建GList类型  
  2. GString *g_string_truncate(GString *string, gint len):截取指定长度的字符串  
  3. GString *g_string_append(GString *string, gchar *val):末尾追加字符串  
  4. GString *g_string_append_c(GString *string, gchar c):末尾最加单个字符  
  5. GString *g_string_prepend(GString *string, gchar *val):开头插入字符串  
  6. GString *g_string_prepend_c(GString *string, gchar c):开头插入单个字符  
  7. void g_string_sprintf(GString *string, gchar *fmt, ...):格式化字符串  
  8. gchar *g_strdup (const gchar *str):复制字符串,返回一个新分配的字符串。  
  9. gchar *g_strndup(const gchar *str, gsize n):复制指定个数的字符串,返回新分配的字符串  
  10. gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle):在限定长度内,第一次出现指定字符的指针  
  11. gchar *g_strrstr(const gchar *haystrack, const gchar *needle):搜索字符串haystack中最后一次出现的串针。  
  12. gchar *g_strrstr_len(const gchar *haystrack, gssize haystrack_len, const gchar *needle)  
  13. gboolean g_str_hash_prefix(const gchar *str, const gchar *prefix):返回字符串是否以某个前缀开头  
  14. int g_strcmp0(const char *str1, const char *str2):对比两个字符串  
  15. gchar **g_strsplit(const gchar *string, const gchar *delimiter, gint max_tokens):分割字符串,保存为数组  
  16. gchar *g_strconcat(const gchar *string1, ...):字符串拼接  
  17. gchar *g_strjoin(const gchar *separator, ...):以某个字符串隔离并拼接  

更多 http://gtk-doc-cn.googlecode.com/svn/docs/glib/glib-String-Utility-Functions.html#g-strdup


六、错误处理

[cpp] view plain copy
  1. gchar *g_strdup( const gchar *str ):替代strdup函数。把原字符串内容复制到新分配的存储块中,返回指向它的指针。  
  2. gchar *g_strerror( gint errnum );  
  3. void g_error( gchar *format, ... );错误提示:“ ** ERROR ** ”并且退出程序。仅用在致命错误上。  
  4. void g_warning( gchar *format, ... ):错误提示:“ ** WARNING ** ”  
  5. void g_message( gchar *format, ... ):在传递字符串前打印"message"  
  6. void g_print( gchar *format, ... ):替代printf函数  


除了上述之外,GLib还提供了很多功能,包括编码转换、正则、XMP解析、Test框架等等。


glib about thread,mutex,cond


[cpp] view plaincopy
  1. #include <glib.h>  
  2. #include <stdio.h>  
  3.   
  4. static int num = 0;  
  5. GMutex mutex;  
  6. GCond cond;  
  7.   
  8. gboolean _thread_main1(void *data)  
  9. {  
  10.     while(1)  
  11.     {  
  12.           g_mutex_lock(&mutex);  
  13.         while(num <= 0)  
  14.         {  
  15.             g_printf("consumer[%d] is wating.....\n",(int)data);  
  16.             g_cond_wait(&cond, &mutex );  
  17.             g_printf("consumer[%d] wake up.....\n",(int)data);  
  18.         }  
  19.         g_printf("consmuer[%d] before,num = %d.....\n",(int)data,num);  
  20.         num--;  
  21.         g_printf("consmuer[%d] after,num = %d.....\n",(int)data,num);  
  22.         g_mutex_unlock(&mutex);  
  23.         sleep(1);  
  24.     }  
  25.     return TRUE;  
  26. }  
  27.   
  28.   
  29. gboolean _thread_main2(void *data)  
  30. {  
  31.     while(1)  
  32.     {  
  33.           g_mutex_lock(&mutex);  
  34.         num++;  
  35.         if(num > 0)  
  36.         {  
  37.             g_printf("prepare to sigal...please wait for 5 seconds\n");  
  38.             sleep(5);  
  39.             g_cond_signal(&cond);  
  40.             g_printf("after g_cond_signal\n");  
  41.         }  
  42.         g_mutex_unlock(&mutex);  
  43.         sleep(2);  
  44.     }  
  45.     return TRUE;  
  46. }  
  47.   
  48.   
  49. int main( int argc,char *argv[] )  
  50. {    
  51.     GThread *consumer1 = NULL;  
  52.     GThread *consumer2 = NULL;  
  53.     GThread *consumer3 = NULL;  
  54.       
  55.     GThread *thread2 = NULL;  
  56.       
  57.       
  58.     g_mutex_init(&mutex);  
  59.     g_cond_init( &cond );  
  60.       
  61.     consumer1 = g_thread_new("consumer1", (GThreadFunc)_thread_main1, (void*)1);  
  62.     consumer2 = g_thread_new("consumer2", (GThreadFunc)_thread_main1, (void*)2);  
  63.     consumer3 = g_thread_new("consumer3", (GThreadFunc)_thread_main1, (void*)3);  
  64.       
  65.     thread2 = g_thread_new("thread2", (GThreadFunc)_thread_main2, NULL);  
  66.       
  67.       
  68.     g_thread_join (consumer1);  
  69.     g_thread_join (consumer2);  
  70.     g_thread_join (consumer3);  
  71.       
  72.       
  73.     g_thread_join (thread2);  
  74.     return 0;    
  75. }    
  76.      

结果:

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.....

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

11-散列3 QQ帐户的申请与登陆 (25 分)

实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是&#xff1a;据说现在的QQ号码已经有10位数了。 输入格式: 输入首先给出一个正整数N&#xff08;≤&#xff09;&#xff0c;随后给出N行指令。每行指令的格式为&#xff1a;“命令符&#xff08;空格&#xff09;QQ号码&…

glib字符串

学过面向对象语言的同学一定都知道String类&#xff0c;一定知道这个类对字符串的操作是多麽的方便&#xff0c;但是c语言中是没有这个类&#xff0c;甚至没有类的概念&#xff0c;但是glib帮我们做的这个“类” GString 除了使用gchar *进行字符串处理以外&#xff0c;Glib还…

KMP 串的模式匹配 (25 分)

给定两个由英文字母组成的字符串 String 和 Pattern&#xff0c;要求找到 Pattern 在 String 中第一次出现的位置&#xff0c;并将此位置后的 String 的子串输出。如果找不到&#xff0c;则输出“Not Found”。 本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试…

命令行工具tshark使用小记

1、目的 写这篇博客的目的主要是为了方便查阅&#xff0c;使用wireshark可以分析数据包&#xff0c;可以通过编辑过滤表达式来达到对数据的分析&#xff1b;但我的需求是&#xff0c;怎么样把Data部分导出来&#xff0c;因为后续的工作主要针对数据包的Data部分&#xff0c;主要…

winshark重要数据结构

说起来有一些惭愧&#xff0c;研究wireshark有一段时间了&#xff0c;但是对源代码的分析却至今没有什么进展。。。 最初想要研究wireshark是因为我的开题是基于wireshark来做的。 现在有很多抓包工具&#xff0c;wireshark的优势在于完全开源&#xff0c;分析功能强大&#xf…

C语言写数据库(二)

简单的实现增删查改的操作后&#xff0c;实现了一个先读写其中一个表的某两项内容&#xff0c;再把相关字符段写入到另外一张表中去。涉及到查询和插入两个步骤。 其中还涉及到汉字的读写和插入&#xff0c;会有字符的操作产生乱码。所以要先保证mysql的汉字字符编码&#xff0…

wireshark源代码分析

各位亲&#xff0c;不是我不想回复你们的问题。是我也不了解。不能误导。希望大家相互帮助。看看能否帮那些提问的小盆友们回复一下呢&#xff1f; 这些都是转载的&#xff0c;如果实在没有办法&#xff0c;可以打开链接到原作者哪里去提问试试看。。。 经过多次尝试&#xf…

C语言写数据库(三)

遇到的问题以及解决思路方法 1.外部导入数据库文件 进入mysql&#xff0c;创建数据库sh_robot source /home/exbot/sh_robot.sql 查看数据库编码格式 show variables like “%char%”; 2.数据库插入操作 进入相关数据库&#xff1a;use 数据库名&#xff1b; 查询存在该表是否存…

Makefile(一)

在一个文件夹中建一个c文件 //main.c #include<stdio.h> int main() {printf("version 1.0");return 0; } 在当前目录下编写makefile文件 //makefile: test : main.o //一种依赖关系声明&#xff0c;生成test可执行程序需要以来main.o文件gcc -o test main.…

Defunct进程 僵尸进程

在测试基于 DirectFBGstreamer 的视频联播系统的一个 Demo 的时候&#xff0c;其中大量使用 system 调用的语句&#xff0c;例如在 menu 代码中的 system("./play") &#xff0c;而且多次执行&#xff0c;这种情况下&#xff0c;在 ps -ef 列表中出现了大量的 defunc…

make文件基础用法

参照&#xff1a;https://www.jianshu.com/p/0b2a7cb9a469 创建工作目录&#xff0c;包含一下文件 main.cperson.cb.hc.h/*** c.h ***/ //this is c.h /*** b.h ***/ //this is b.h /*** main.c ***/ #include<stdio.h> //#include"a1.h" //#include"b.h&…

一个Linux下C线程池的实现(转)

1.线程池基本原理 在传统服务器结构中, 常是 有一个总的 监听线程监听有没有新的用户连接服务器, 每当有一个新的 用户进入, 服务器就开启一个新的线程用户处理这 个用户的数据包。这个线程只服务于这个用户 , 当 用户与服务器端关闭连接以后, 服务器端销毁这个线程。然而频繁地…

二维数组作为函数参数

#include<stdio.h> //#include<> //二位数组作为函数参数时&#xff0c;可以不指定第一个下标 void print_buf(int (*p)[3],int a,int b) //void print_buf(int p[][3],int a,int b) {int i,j;for(i 0 ; i < a; i){for(j 0; j < b; j){printf("p[%…

mystrcat

#include<stdio.h> //如果一个数组做为函数的形参传递&#xff0c;那么数组可以在被调用的函数中修改 //有时候不希望这个事发生&#xff0c;所以对形参采用const参数 //size_t strlen(const char *s); //strcpy(char* s1,const char* s2); void mystrcat(char *s1,cons…

关于非阻塞的recv的时候返回的处理

注意recv&#xff08;&#xff09;如果读到数据为0&#xff0c;那么就表示文件结束了&#xff0c;如果在读的过程中遇到了中断那么会返回-1&#xff0c;同时置errno为EINTR。 因此判断recv的条件&#xff1a; 如果read返回<0 如果0 表示文件结束&…

带参程序

windows环境 #include<stdio.h>int main(int argc, char *argv[]) {printf("argc %d\n", argc);for (int i 0; i < argc; i){printf("argv[%d] %s\n",i, argv[i]);}system("pause");return 0; } windows环境下&#xff0c;带参函数…

Ubuntu安装mysql步骤

1.打开终端&#xff0c;输入&#xff1a; sudo apt-get updata 输入root用户密码 2.更新完毕后&#xff0c;输入 sudo apt-get install mysql-server ubuntu14.04安装中间会让你设置密码&#xff0c;输入密码后点击确认(mysql123) 3.安装结束后&#xff0c;查看端口号是否开启 …

Pthread创建线程后必须使用join或detach释放线程资源

这两天在看Pthread 资料的时候&#xff0c;无意中看到这样一句话(man pthread_detach): Either pthread_join(3) or pthread_detach() should be called for each thread that an application creates, so that system resources for the thread can be released. …

二维数组求平均值(指针的使用)

#include<stdio.h>int main() {int buf[3][5] {{1,2,3,4,5},{4,5,6,7,8},{7,8,9,10,11}};int i;int j;//求行平均值 for(i 0; i < 3; i){int sum 0;for(j 0; j < 5; j){sum (*(*(buf i) j));}printf("sum %d\n",sum/5);}//求列平均值for(i 0; i …

linux终端关闭时为什么会导致在其上启动的进程退出?

现象 经常在linux下开发的人应该都有这样的经验&#xff0c;就是在终端上启动的程序&#xff0c;在关闭终端时&#xff0c;这个程序的进程也被一起关闭了。看下面这个程序&#xff0c;为了使进程永远运行&#xff0c;在输出helloworld后&#xff0c;循环调用sleep&#xff1a; …