网络服务器软件开发/中间件开发,关注ACE/ICE/boost

C++博客 首页 新随笔 联系 聚合 管理
  152 Posts :: 3 Stories :: 172 Comments :: 0 Trackbacks

   几乎每个像样的库,都会有自己定义的类型系统,如U8,U16等等,下面是摘选自resiprocate-1.4\rutil\stun\Stun.hxx的,
   

#ifndef RESIP_COMPAT_HXX
// define some basic types
typedef unsigned char  UInt8;
typedef unsigned 
short UInt16;
#ifdef __APPLE__
typedef unsigned 
long   UInt32;
#else
typedef unsigned 
int   UInt32;
#endif
#if defined( WIN32 )
typedef unsigned __int64 UInt64;
#else
typedef unsigned 
long long UInt64;
#endif
#endif

typedef 
struct { unsigned char octet[16]; }  UInt128;
   随着64位服务器的逐渐普及,int类型在32位和64位机下代表的字节数可能不再相同,这对现有的服务器的协议解析会造成一定麻烦,比如,协议解析时,可能有,
int nCmdType = (int)ptr;
ptr += 4;
   所以,自己在开发底层库时,封装一下基本类型,既提高了可读性,也易于移植
posted on 2009-02-02 10:51 true 阅读(3041) 评论(12)  编辑 收藏 引用 所属分类: C++基础linux

Feedback

# re: 对基本类型的再包装,方便了移植 2009-02-02 21:18 Dancefire
在1999年以前,你这么做是合理的。但是1999年C99标准推出以后,这样做就已经不合理了。你应该使用C99的标准头文件<stdint.h>,如果是C++的话,应该使用<cstdint>。

在stdint.h中,标准明确要求定义:

int8_t;
int16_t;
int32_t;
int64_t;



uint8_t;
uint16_t;
uint32_t;
uint64_t;

有关C99的stdint.h的信息请参考wikipedia上的介绍:
http://en.wikipedia.org/wiki/Stdint.h
http://www.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html

c++委员会已经把cstdint纳入TR1中,并已经列入c++09的标准中,今年内就会称为c++标准的一部分。

这些类型的定义,将有所用的编译器和库保证其平台间一致性。gcc和unix下很多C或者C++编译器的用户已经随时可以使用<stdint.h>或者<cstdint>,因为gcc支持c99标准,并且libstdc++也包含了<cstdint>。至于Windows用户而言,稍有不幸,因为微软的编译器不支持c99标准,所以没有<stdint.h>这个文件,这也可能是楼主不知道这个文件的主要原因。但是没关系,boost库提供了tr1的完整实现,其中自然包含了<cstdint>,只要引入<boost/cstdint.hpp>就可以使用上述类型而不用担心跨平台性。当然,一如既往,boost提供了更多的可移植性基础类型的定义。

http://www.boost.org/doc/libs/1_37_0/libs/integer/cstdint.htm

请楼主参考这些信息修改文章,毕竟在标准可用下,使用标准更合理。  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 08:59 true
@Dancefire
谢谢,你的提醒!刚才查看了linux,在/usr/include目录下存在stdint.h,但在windows下没有此文件:VC6和VC8下都没有,不知道VC9下如何。像这种情况,也只能自己定义了  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 11:37 陈梓瀚(vczh)
C99相当一部分不在C++里面,所以微软的编译器不支持是很正常的。  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 12:00 Dancefire
@true

我的回复中已经提到,因为微软尚不支持c99标准,因此vc用户享受标准提供的便利会有些麻烦。

但是我也提到了,<cstdint>已经被提到TR1并且进而提到了c++09标准中了,因此,各大编译器已经都开始支持<cstdint>了。对于gcc用户自然没问题。对于vc用户,有很多
种办法可以提前使用c++09的一些库:

1) 下载微软vc2008 Feature Pack,里面提供了TR1的实现,其中包含我提到的头文件。

2) 更简单一些,安装boost,使用<boost/cstdint.hpp>文件,里面也是按照TR1标准/c99标准实现的跨平台统一的类型文件。

3) 使用第三方的c++标准库,如apache的stdcxx,里面也基本上支持了TR1,包含了我说的头文件。

因此完全不用自己定义。更何况自己定义的很难符合跨cpu,跨系统的统一性。而我说的这些实现,由于按照标准,已经支持几十种系统和cpu的组合了,为什么还要自己定义呢?拿来用就好了。

如果仅仅是担心vc和其它环境不兼容,那大不了从mingw中把stdint.h拷过来,然后按照vc环境改一改就可以了。这样在vc环境下include这个头文件,其它环境下使用标准头文件。除了微软外的编译器基本上都支持c99,因此不用担心其他平台的兼容性。

  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 12:38 true
@Dancefire
你说的这三种方法,目前都不能实现,公司的系统不能使用第三方库,现在ace也放弃了,而且需要兼容VC6,各种 版本的linux。类似的问题,还有__VA_ARGS__等。这样虽然会有造轮子的嫌疑,但长期来看,对系统的维护会更容易,得大于失吧。  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 12:56 Dancefire
@true

那就不使用第三方库好了。boost的头文件可以直接拷过来用,修改一下当成自己的,算不得第三方库了吧?或者从mingw中把stdint.h拷过来也行,那个是针对win32平台修改过的stdint.h。就一个头文件而已,也算不得第三方库吧?对于这个头文件而言,VC6是肯定兼容的,最多稍微修改一下不会太费力气。

对于类型而言,应该使用标准所制定的跨平台一致性类型。但是vc不支持,因为我们添加个头文件让其支持标准。这样就可以保证和所有支持c99系统的一致性了。比如linux,甚至freebsd或者netbsd,或者darwin/macos。

所以,在已存在标准这个前提下,那么问题应该描述为如何为vc补全所需标准的内容。这很简单,遵循标准定义,或者直接那别人已经定义好的头文件过来就ok了。也不依赖任何第三方库。

关于你说的__VA_ARGS__,也是C99标准的一部分,所有支持c99的编译器都支持,包括gcc。
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

VC2005开始以后都支持了。
http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx

因此之前的版本如果不支持,那应该设法为vc6定义一个__VA_ARGS__的宏,来使之支持相应的标准。

原则就是,凡是在标准中已经明确定义的东西,那么谁不支持标准,就让谁符合标准。而不要自己重复造轮子,因为你无法保证你定义的类型在多系统下兼容,毕竟你接触和使用的系统有限。何不只让不符合标准的符合标准,至于其他支持标准的系统,自然不用你来操心。
  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 13:29 true
@Dancefire
你的回复很好“凡是在标准中已经明确定义的东西,那么谁不支持标准,就让谁符合标准”是一种思路,只考虑win和linux,看下面lib.h这种用法

#ifdef WIN32
typedef unsigned char int8_t;
typedef unsigned short int16_t;
#else
#include <stdint.h>
#endif
我觉得还是很少这样写的,在导出的头文件lib.h中,最起码现在我用的2个商用平台没有这样的--->导出的lib.h中都不会再包含其他头文件  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-03 16:28 Digital_life
从你们的对话中受益良多,  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-04 09:03 梦在天涯
@Dancefire
很不错!说的很好啊!  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-04 09:08 梦在天涯
@Dancefire
的意思是说要想编写可以跨平台的程序,就要用UInt32,等,不直接使用int,long等吗?  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-02-04 09:48 Dancefire
@梦在天涯
不是自定义的UInt32,而是标准中的uint32_t或者,int32_t之类。自定义的类型是无法保证这一点的。

是否使用这类确保跨平台一致性的类型,关键在于你的应用在使用这些类型的时候是否关注其大小。比如你仅仅是进行个for-loop,或者简单的计数或者确定数字不是很大的计算,那自然无所谓了。

但是比如你要把一个数字以二进制格式存储到硬盘上,或者要进行网络通讯,其内容是某结构体等,或者某些变量需要至少多少位的空间才能够满足需求。碰到这类比较关心实际占用空间大小的问题,而且系统是跨平台的,那么就需要考虑使用标准中具有跨平台一致性的类型了。那些是由编译器会保证跨平台大小一致的。  回复  更多评论
  

# re: 对基本类型的再包装,方便了移植 2009-06-19 09:25 dvb-dvb
我也遇到这个问题了,
TS Analyser TooL:
http://www.cnitblog.com/dvb-dvb/archive/2009/03/20/55573.html  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理