随着64位windows的慢慢普及,现在做windows下的应用开发,尤其是系统的一些插件的开发(IE、Explorer等),越来越需要同时开发32位和64位的版本了,这就要我们在写代码的时候尤其注意对指针和整型数据的操作,以避免出问题。
同一份代码,可以根据Platform为Win32或X64来产出对应的版本,这是我们的目的。
字长模型
指针类型一般是跟随系统位数的,32位系统下指针为32位,64位系统下指针为64位,这个一般不会混淆,但是来到整型数据类型的时候,这里就有字长模型的区别了。
字长模型中I表示int,L表示long,P表示pointer,LL表示long long,如ILP32指int、long、pointer都是32位,LLP64指long long和pointer是64位。
32位系统有ILP32和LP32两种,64位系统有LP64、ILP64、LLP64三种,这都是常见的字长模型,出现这些模型的原因是C/C++语言并有没有规定诸如int、long等这些整型的长度,只是规定了这些类型的长度下限和相互的大小关系(如short <= int <= long <= long long),具体的实现由各个编译器自行决定。
我们先来看一下在不同的字长模型下,不同整型所占用的空间大小:
LP32 | ILP32 | LLP64 | LP64 | ILP64 | |
---|---|---|---|---|---|
char | 8 | 8 | 8 | 8 | 8 |
short | 16 | 16 | 16 | 16 | 16 |
int | 16 | 32 | 32 | 32 | 64 |
long | 32 | 32 | 32 | 64 | 64 |
long long | 64 | 64 | 64 | 64 | 64 |
pointer | 32 | 32 | 64 | 64 | 64 |
Visual C++使用的字长模型
VC的32位字长模型是ILP32,而64位字长模型是LLP64,这是因为从32位往64位迁移的时候,为了尽量减少兼容性的问题,所以除了指针的位数从32位升到64位之外,其他整型的长度都没有变化。所以用vc进行64位程序开发和32位程序开发最大的不同就是指针的大小。
另外,long long是C99才引入的,所以是VC6之后才支持这个类型,相比与long long,windows下更常用的是__int64(long long也是__int64 typedef的)
类UNIX系统的各类编译器在64位下一般都是使用LP64字长模型。
32位/64位程序一体开发
要达到一套代码自适应32位和64位,我们就需要用到windows给我们定义的两套数据类型,一种是精准的数据类型,其不论在32位还是64位下大小都是一样的(一般以长度结尾),如DWORD32、DWORD64、INT32、INT64、UINT32、UINT64等;另一种就是所谓的“多态类型”,其长度以指针的长度作为基准(一般以_PTR结尾),常用的有:LONG_PTR、ULONG_PTR、UHALF_PTR(无符号指针长度的一半)、LPARAM、WPARAM(即UINT_PTR)
总的来说,指针我们一般都要使用_PTR这种类型,如果需要确定长度的就使用精确类型,其他情况普通类型也可以胜任。