浅谈Windows系统下C语言编程中Glib库的使用
在这个C的变成世界里,有许多实用的库,其中最有名的且最通用(跨多个平台的实现包括Windows,要知道很多实用的编程库都不提供Windows的实现)就是GLib这个库,其中就有实现线程的部分。
glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性。
glib是Gtk +库和Gnome的基础。glib可以在多个平台下使用,比如Linux、Unix、Windows等。glib为许多标准的、常用的C语言结构提供了相应的替代物。
如果在程序中要使用到glib库中的函数,则应该包含glib.h头文件(在gtk.h和gnome.h头文件中已经包含了glib.h了。
但是,因为这是中文的,看的人自然不是歪果仁,中国编程新手大都还是习惯用 Windows 环境,也不做强求,仁者见仁智者见智,后续会有一个程序作为例子,其中简单的应用了多线程的知识来写一个备份软件,线程的实现是用的 Windows 自己的接口,所有这些接口都能在 MSDN 里查找到相应文档。
Glib库在Windows下的配置
之所以不说 *nix 系统下的配置是因为,哪里的配置太无脑了,特别是Ubuntu,一句命令+有网络基本就配置完毕了。
使用的是稳定版的2.28.8版本,截至目前可用的最高稳定版本为2.46.x版本
将预处理配置好一些步骤的glib打包放在我的网盘中,可以直接下载,添加IDE的路径就能使用,这是对于 Visual C++ 系列编译器能用,如果用 MinGW 系列的编译器就需要重新编译
如果想自己配置,也可以前往这个网址进行下载,或者前往GNU项目主页下载最新的源码以及工程文件自我编译,方式有很多,不使用现有二进制而自行选择编译的大概莫过于想使用MinGW,在MinGW项目的主页也有介绍
如果资源太少,可以参考如何编译GTK项目的方法,因为GLib的前身便是GTK的一部分,只不过后来独立出来了。
微软的宇宙级编译器Visual Studio对于C89(C90)之后的标准并不支持,但是对其中的特性却早早进行了实现(即没有可开启标准的选项,但是新标准所说的特性它都拥有,都能够使用,甚至还要更加超前)
故接下来的备份程序将使用Visual Studio 2013 进行编写。
配置glib-2.28.8
下载编译好的二进制包,预处理好(某些操作,不多说,网上有教程,记得用谷歌,或者到博客园里找类似的,但是版本比较老可能和我用的有一些出路,但可以依着葫芦画瓢)以后,将路径配置到工程里:
创建一个Win32程序,并且在属性管理器(左侧栏下部寻找)中创建属性表(Debug和Release各创建一个,设置都相同即可)
打开新建的属性表
通用属性->VC++目录->包含目录->编辑 添加下载下来的文件中的glib\glib2.28\include目录,不放心的还可以再添加一个glib\glib2.28\lib\glib-2.0\include目录
通用属性->VC++目录->库目录->编辑 添加glib\glib2.28\lib目录
通用属性->链接器->输入->附加依赖项 添加glib\glib2.28\lib目录下的所有.lib文件,即将这些文件的名字都手动输入进去,如果使用我的这个版本的话那就是
gio-2.0.lib glib-2.0.lib gthread-2.0.lib gmodule-2.0.lib gobject-2.0.lib
通用属性->C/C++->代码生成->运行库开启多线程/MT
Okay!成了
休息一下
其实对于C程序员而言,最重要的莫过于使用一系列开源库,而不是对新标准的追求,因为越低的标准越容易跨平台,对于库而言这是先辈总结的一系列实用的数据结构和算法,甚至是实用的框架。我们不一定需要配置他们,而是从里面吸取一些他们的技术,转为自己的代码,毕竟库对于很多程序员编写的程序来说都大材小用了,但有时候又不得不使用一些必要的数据结构和算法。
在大学的这几年里,也许是因为不过是一个吊车尾的一本,所以我无法感受到老师教授带来的教导,但是也使得我深深的接触到了开源,开源给予了我很多,比如更开阔的编程思路,更广阔的心胸,更有进步的动力,更多的小伙伴。当然也知道自己的渺小。
是很多人(比如知乎的回答人和提问者),都提到要多观看C的源代码, 但是这对于初学者,甚至现在的我感觉也不是一件容易的事,更遑论初入门的同学了,特别是对于许多上个世纪的大神,为了节省空间以及提高效率,简直是无所不用其极!虽然某些用法能够被现代接受,但是你能在第一眼就看出来,为了构造一个红黑树节点,把树的指针和节点的颜色信息都隐藏在一个指针地址里吗?
/* 假设有一个节点的指针 p_node */ node_color = p_node->node_color & 1; /* 原理就是用最后一位bit来存储颜色 */
其中在 Linux 里, p_node->node_color 被设定为无符号的长整形,以整数型式存储指针和颜色信息,而不是用指针类型。
node_pointer = (node_type*)p_node->node_color & ~3;/* 清除最后两位上的bit的值 */
也就是清除颜色信息,留下的就是指针的值,即地址。
为什么呢,只要我么能够保证节点的创建位置是32位/64位对齐的,我们就能够保证它的最后两位/三位是空的,绝对不会被使用的。
/* 32位 */ sizeof(void*); /* 是 4 */ /* xxxx xxxx xxxx xxxx xxxx xxxx xxxx xx00 */ /* 64位 */ sizeof(void*); /* 是 8 */ /* 前方省略48位 xxxx xxxx xxxx x000 */
意思就是,对于指针而言,因为编译器要保证寻址的高效所以它在给分配地址的时候,会对齐内存中的地址,按照指针大小的倍数对齐,这就会导致不同位的程序的指针变量的值中有几个bit 会没有使用,则用它来存储。
具体的情况,网路上的详细解说十分之多,开一个头就好。但是这真的是我们一开始就应该接触的吗?
是
怎么说,在很多的时候,C语言给我们的函数都不够安全可靠,但是在我们无法使用新标准提供的函数的情况下(十分常见)我们该如何做呢?当然是自己写,怎么写更完美,自然是看看别人怎么写,而不是自己一抹黑的乱来,因为事实证明,自认为好的到最后都会摔一跤,虽然不是坏事。
最简单的做法便是用宏包裹一下,做一些预处理,或者对于宏机制不太喜欢的人会选择用一个函数进行包裹,也未尝不可。
注
写在最末尾,填几个前面挖的坑。
不知道是不是故意的,一般GNU项目的子主页面上,找不到(很难找到)对应的项目的下载地址,也就是光看着介绍如何如何牛,如何如何好用,但就是不告诉你去哪里下,这时候,首先确认你要下的这个软件的名字,然后去GNU项目首页里的程序列表里找,在哪里一定能找到,而不是在那些介绍页面乱点,结果根本找不到。
最典型的就是一个叫做GMP的开源软件,用来自行编译MinGW用的依赖,希望能警醒各位。
之所以用2.28.8而不是2.46.x是因为我实在不想自己在Windows上编译了,因为大部分时候,写程序都是在 Linux 上,所以就偷懒一下。
对于我的文件是不是有毒,我说有毒,有一种叫做叫你再用Windows编程的毒。
好吧其实我承认Visual Studio的确是宇宙无敌的编译器。
末尾
接下来的第三部分我会用一个备份程序来贯穿
操作系统 : Windows
跨平台 : 否
API调用 : Win32 API
编译器 : Visual Studio 2013
语言 : Pure C Programing Language
会在里面介绍一下,常在开源代码中看见的一些奇怪的东西,例如
#ifdef __cplusplus extern "c" { #endif ... #ifdef __cplusplus } #endif