Windows 64Bit移植心得

下半年公司有一个Windows下64Bit移植的项目,已经厌倦之前百无聊赖的维护工作的我,有幸接到了这项工作。废话不多说,接下来谈谈Windows下64Bit移植的心得。

 

项目特点: Visual Studio 2005 (包括MFC应用程序以及Win32 DLL) + WDK7000 (驱动程序) 环境

 

移植基本步骤:

1. 调整项目文件目录结构

    心得1: 调整目录结构的原因是同时支持64Bit和32Bit的编译,这时候可能对应的要修改很多脚本来应对这些目录的变化。

2. 追加64Bit编译配置项,调整编译环境

    心得1: 对于VC项目,记得在追加了x64编译选项的时候,追加_WIN64的宏定义。 按照MSDN的说法,_WIN64和_AMD64_对于64Bit编译环境应该是默认存在的,而且_WIN32宏并不需要去掉。 (因为像RC文件也许要这样的宏,直接在Visual Studio中一个一个添加实在会把人累死,建议可以通过脚本修改)

 

    心得2: 对于使用WDK环境,如果支持从XP到Win7的多个操作系统,一定要注意NTDDI_VERSION, _NT_TARGET_VERSION, _WIN32_WINNT的指定(否则可能编出来的DLL压根不能用)。 32Bit项目支持一些较早的系统(如Win2000),显然64Bit项目应该是与时俱进的。

 

    心得3: 记得WinSXS与DLL Hell的事情,一定要检查manifest文件,或者linker声明中对于系统特定版本DLL的依赖关系。32Bit项目下可能支持了特定版本的DLL(比如6.0的comctl32.dll)。 64Bit也一定要支持。

 

    心得4: 如果整个项目(VS+WDK)由统一的脚本控制编译,一定要注意编译器,链接器的路径冲突问题(防止用VS2005的编译工具去编WDK的代码)。 还有就是一些lib文件引用的冲突问题。控制好各种PATH环境变量很重要。

 

    心得5: 不要相信VS的版本移植所执行的conversion。如果从VS2003升级到VS2005, 记得检查一下配置中有哪些配置被弄丢了。比如对manifest文件的依赖

3. 修改部分代码,或者重写部分代码

    其实这里本应是64Bit移植的重头戏,如果之前的代码写的好的话, 这里基本不用什么大的调整了。可是大部分年代久远的系统,多半在产生之初都没有考虑过64Bit系统,可能那个时候amd64还没有, ia64又太激进。 代码中存在着各种稀奇古怪的bomb,一定要扫干净。

 

   心得6: 类型,类型, 还是类型

  数据类型的扩展可谓是64Bit系统与32Bit系统最大的不同,数据寻址范围增大到64位长度,指针类型扩展到64位长度,数据结构变成8字节对齐,位操作的变量很可能需要应对高32位的扩展。因此,类型,特别是各种数据类型的长度应该是bomb最密集的区域。

 

    应对这些问题,有以下几种实践中好用的方法:

    1. 重视编译过程中产生的warning。现在的编译器都很强大,对于类型及长度发生的变化,它是最直接的反应。

    2. 除了编译器,可以使用静态代码分析工具。

    3. 一定要检查每一处强制类型转换,"每一处"听起来有点可怕。可以通过正则表达式将这些强制类型转换都找出来。

    4. 在Windows系统中,特别要注意DWORD类型,WPARAM, LPARAM, LRESULT, size_t等, 以及各种PTR结尾的类型。 因为32Bit系

        统中,他们很可能都用来保存指针或者范围。

 

   心得7: 与长度有关的函数

   一定要小心这些与长度相关的函数,文件长度,数组长度,内存范围, 这些东西从2^32次方的访问范围,增大到了2^64次方的范围,一个不小心,溢出就等着你。

  

   心得8: 如果能回到过去

   如果回到32Bit项目编码的一开始,你必须要记住以下几件事情,否则噩梦会伴随着你的:

      

      1. 函数声明,定义一定要匹配。 特别是C代码,编译器有时候对是检查不错来这种事情的。

      2. 尽量不要用强制类型转换,也不要图方便用一些被typedef或者#define出来的同类型不同名的类型声明。

           不要随便使用你认为的类型相同类型名,应该好好阅读系统建议你应该使用的类型名。也就是针对特定的场合,使用特定的类型名。

      

           表示长度的时候,尽量使用size_t

           表示指针操作的时候,尽量使用ptrdiff_t

           LPARAM, WPARAM 不要用DWORD取代

           LRESULT以及各种PTR结尾的类型不要用int或者unsigned int取代

           指针不要存在DWORD变量中

           。。。。。。

      

      3. 要注意数据接口,特别是保存或者度入的数据。

           因为程序导出和读入的数据有可能需要在32Bit和64Bit系统上共享。因此,到出的数据中,尽量不要使用长度发生变化的类型。对于数

           据存取,最好限定在BYTE, WORD, DWORD, QWORD这些固定的数据类型上。

4. 进行系统以及应用程序兼容性测试

    移植有时候会有一些不那么显而易见得问题产生,特别是Windows系统之间也有许多差异。步骤3中的动作,基本上是移植中的已知问题,但是还有许多未知的潜在不兼容性存在。而这些,是在设计之出很难考虑到的。所以兼容性测试是必须要做的,而且是大规模的回归测试。

    尽管如此大规模的全面测试,这里我已经有一些应该牢记的兼容性问题,

   

   心得9: 子进程与权限提升

    WinExec, CreateProcess函数与ShellExecute函数都是用来创建子进程的函数。根据微软官方的说法,WinExec, CreateProcess函数并不支持子进程的权限提升。在Vista以后的系统中,用这两个底层函数创建安装程序进程将导致无法安装(没有权限)。 而ShellExecute被是较为高层的用户函数,它是支持权限提升的。 虽然微软这么说,但实际上这只发生在64Bit系统上。(可能默认情况下32Bit已经被修整了) 。 因为实际上32Bit下WinExec, CreateProcess仍然可以提升权限,这可能导致这个问题被忽视。

 

    心得10: ToolTipInfo结构体大小与comctl32.dll版本

    奇怪的问题,ToolTipInfo结构体大小必须剪掉一个指针的长度,才能在多数64Bit系统中正常运作。

 

    心得11: MFC中的OnCancel事件与OnQueryCancel事件

    两者的用法有区别,但32Bit下有人把它们随意的使用。结果,64Bit下会发生你把电脑砸了也想不到的现象发生。

 

以上就是这半年来在64Bit移植上的心得。暂时想到这么多,还比较凌乱,以后慢慢整理吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值