C++开发框架
一些稳定的、可信赖的 c 语言通用功能库
可是,它们是那么庞大厚重,就算拥有模块化导入的设计,我也还是觉得,这是把牛刀,我杀鸡不能用它。我要的,就是一个提供了基础功能的,而且很多人都用过的,经历了各种风霜依然稳定的通用库。 有了它,我才能装酷。各位宅,你们有知道满足类似需求的库吗?求推荐。跨平台方案研究
对于一个软件来说,一般都会碰到几种广义上的平台特性,特别对于跨平台的网络程序来说。
1、硬件指令环境:比如说英特尔、摩托罗拉等芯片机器指令都有所不同
2、操作系统环境:不同操作系统或者同一操作系统的不同版本都存在需要兼容的特性
3、编译软件环境:现在很多IDE都不一样,即使象C++这样具有统一标准的语言,都会被相应的扩展
跨平台方案首先要解决这3个问题。一般来说,我们写的都是应用级别的软件,硬件环境可以由操作系统或者编译软件来处理,不需要太多的关心,但还是有一些细 节不得不注意,比如说字节顺序,大端还是小端。一些对性能要求比较高的软件,比如Apache和GCC,多针对不同的指令集做相应的优化。
在很多IDE环境中,都会预先设定宏来指示编译环境,比如什么指令集,什么操作系统。在通常情况下,我们都会以这样的方式来编写跨平台代码:
#ifdef LINUX
...
#else
...
#endif
利用编译软件为我们提供的宏来区分上面3种情况,这种方法比较简单,但在大型软件中,会让整个源码中充斥着宏,大大降低了源码的可读性,而且很难维护这些源码。首先改动一下功能,都必须考虑对其他模块的影响,以及对其他模块在不同平台上行为的影响。
我们指定3个源码库作为跨平台的研究目标,STL、BOOST、APR,这3个库都是可以跨平台的源码级别的库,而且解决的问题都不完全重叠。比如STL 更多定义的是与平台无关的功能,或者一些已经被标准化的功能。BOOST是对STL的一个扩展,号称是STL的扩展库。APR和前面2者不一样,他完成是 重头开始实现的一个C类型库,可以在不同操作系统,不同编译软件上运行,在局部还针对不同指令集做了优化。
一、STL的跨平台方案是通过文档方式,指定一个标准,由不同的编译器来实现。这种方式的实际意义并不大,因为绝大多数的我们是不可能去制定一个公开的标准,而只能根据不同标准来实现自己的功能接口。
二、BOOST是STL的一个扩展,他封装了很多和平台特别是操作系统相关的特性,如线程。在BOOST的源码中,主要分为2个部分,一个部分是C++类 型的接口,另外一个部分是平台相关配置信息。前一部分主要是平台无关的语法和接口,后一部分主要是平台相关的代码,这部分依据平台特性,实现前一部分提供 的接口。对于用户来说,看到的永远只是前一部分平台无法的语法和接口。我们更关注的是后一部分内容,来研究跨平台方案。
1、配置文件【config】:针对每个环境,建立一个对应的文件,在文件中,对环境进行初始化。这个技巧可以通过config目录可以看出,config目录又分为compiler和platform子目录。
2、平台细节【detail】:有些平台差异无法通过配置来消除,特别是一些缺失的功能,所以在detail目录下对这部分做很多有效的补充。
三、APR是C库,他跨平台技巧比其他2个C++库有更凌厉的表现,我们可以从几个方面来作出总结。
1、预先声明,具体定义留给平台相关的文件。比如文件操作,LINUX和WIN32下的API有很大区别。
<<file.h>>
typedef file_st file_t ;
<<win32/file.c>>
#include "file.h"
struct file_st{
HANDLE handle ;
} ;
<<linux/file.c>>
#include "file.h"
struct file_st{
int handle ;
} ;
在头文件中,只声明了一个类型file_st,这个类型的具体结构并不知道,只有延迟到后来每个平台中才被定义。这个特性在APR中得到充分的应用。和BOOST有些类似,他相当于将整个库分为平台相关和平台无关的2层,但具体技巧还是不太一样的。
2、结构指针
预声明的技巧,允许我们将具体的定义延迟到实现的时候来定义,但遗憾的是,我们同样无法直接使用结构变量,因为这时候必须为编译器指明结构的具体定义,而只能使用结构指针。本来可能是很简单的语法,但我们不得不换种方法,比如:
struct file_st file ;
void init(&file , sizeof(file)) ;
但是现在不行,因为我们在外部引用file.h的时候,实际上并不知道struct file_st里面究竟有些啥东西,而且sizeof(file),也必须知道file的确切结构,才能计算出他的具体大小。所以我们不得不写成这种形式:
struct file_st *file = NULL;
void init(&file) ;
struct file_st是啥样呢?我们不需要知道,由file.c为我们分配这个空间,我们只要得到他的地址就行了。
3、分目录存储平台文件
这个技巧在BOOST也有应用,但主要体现在config目录和detail目录下。而这个技巧在APR中应用十分广泛,你在APR源码中,几乎到处都看到arch目录下,有win32、linux、beos以及其他操作系统的的名字。
对于不同编译软件,APR主要通过工程文件来实现的。比如在根目录下,既有configure.in也有*.dsw文件,如果你是在LINUX下,你就可 以直接是使用configure和make来编译LINUX下的软件。如果你是在WIN32下,也可以使用VC直接打开*.dsw文件。以此类推,每个编 译软件通过这种方式区分开来。 --------------------- 本文来自 romandion 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/romandion/article/details/1763211?utm_source=copy
APR – 被遗忘的跨平台库
提起跨平台库,很多人立刻想到的是C++库,boost、STL、ACE之类的,很少有人会提及跨平台的C库,Apache Portable Runtime,就属于被遗忘的这一类型。
前几天一个很偶然的机会,当了它的源代码并且读了一部分,发现还挺好用的。但是不可能一定完全满足你的要求。
对操作系统底层的抽象很多,无外乎内存管理、进程线程控制、IO、文件系统接口和IPC等,其中对于锁的设计真的很全,甚至在Windows下把posix支持的条件变量和读写锁什么的都自己实现了一遍。仔细看了那几把锁的实现,用的时候还是得小心,例如那把读写锁的适应范围就比较有限。
对数据结构的支持很少,只看到了hash和array,这可能和C程序的弱类型有关,很难像C++一样写出一些类型安全而且又可读性好的数据结构实在是很困难,此外C语言世界里已经有了很多通用的数据结构(例如,平衡树)了,没必要重新发明轮子。