如何移植32位程序到64位系统一.简单介绍64个系统已经为32位的应用程序准备了运行32位程序的环境,这个环境就是WOW64的WOW64是Windows-32-on-Windows-64的缩写。它为现有的32位应用程序提供了32位的模拟,可以使大多数32位应用程序在无需修改的情况下运行在Windows64位版本上。它类似于旧的WOW32子系统,负责在Windows32位版本下运行16位的代码。WOW64的是视窗-32上的Windows-64的缩写。它为现有的32位应用程序提供了32位的模拟,可以使大多数32位应用程序在无需修改的情况下运行在64位版本的Windows上类似于旧的WOW32子系统,负责在的Windows32位版本下运行16位的代码。64位版本Windows中的注册表分为32位注册表项和64位注册表项。许多32位注册表项与其相应的64位注册表项同名,反之亦然。64位版本Windows包含的默认64位版本注册表编辑器(Regedit.exe)可显示64位和32位的注册表项。WOW64注册表重定向器为32位程序提供了对应于32位程序注册表项的不同注册表项。下面介绍一点编程中要用到的东西。1.当然,这里你还必须用到一个就是,如何判断系统是32位系统还是64位系统呢?如果你要用小改变是必须知道现在到底是32,还是64。IsWow64返回TRUE则是64位系统,否则为32位系统。code如下:VC测试通过typedefBOOL(WINAPI*LPFN_ISWOW64PROCESS)(HANDLE,PBOOL);LPFN_ISWOW64PROCESSfnIsWow64Process;BOOLIsWow64(){BOOLbIsWow64=FALSE;fnIsWow64Process=(LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT(kernel32)),IsWow64Process);if(NULL!=fnIsWow64Process){if(!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)){//handleerrorAfxMessageBox(IsWow64error!);}}returnbIsWow64;}2.在64位版本的注册表编辑器中,32位注册表项显示在以下注册表项下:HKEY_LOCAL_MACHINE\Software\WOW6432Node使用默认的64位版本注册表编辑器,可以查看或编辑64位和32位的注册表项和项值。要查看或编辑64位注册表项,必须使用64位版本的注册表编辑器(Regedit.exe)。还可以使用%systemroot%\Syswow64文件夹中的32位版本注册表编辑器查看或编辑32位注册表项和项值。在32位版本注册表编辑器中执行任务的方式与64位版本注册表编辑器没有区别。要打开32位版本的注册表编辑器,请按照下列步骤操作:单击“开始”,然后单击“运行”。在“打开”框中,键入%systemroot%\syswow64\regedit,然后单击“确定”。注意:除非使用-m开关启动注册表编辑器的第二个实例,否则,必须先关闭64位版本的注册表编辑器,然后才能打开32位版本的注册表编辑器(反之亦然)。例如,如果64位版本的注册表编辑器已经在运行,在第2步键入%systemroot%\syswow64\regedit-m可启动32位版本的注册表编辑器。为了支持32位和64位COM注册和程序状态的共存,WOW64为32位程序提供了一种备用注册表视图。32位程序会看到与真正的64位HKEY_LOCAL_MACHINE\Software树完全分开的32位HKEY_LOCAL_MACHINE\Software树(HKEY_LOCAL_MACHINE\Software\WOW6432Node)。这样可以隔离HKEY_CLASSES_ROOT,因为此树的每个计算机部分驻留在以下注册表项内:HKEY_LOCAL_MACHINE\Software为了通过COM和其他机制实现64位/32位程序互操作性,WOW64使用了一个“注册表反射器”来在64位注册表视图和32位注册表视图之间镜像某些注册表项和项值。该反射器是“智能”的,因为它只反射COM激活数据。反射的注册表项WOW64注册表反射器可能会在反射过程中修改注册表项的内容和项值,目的是为了调整路径名等。因此,32位的内容与64位的内容可能会有所不同。下面的注册表项会被反射:HKEY_LOCAL_MACHINE\Software\ClassesHKEY_LOCAL_MACHINE\Software\COM3HKEY_LOCAL_MACHINE\Software\OleHKEY_LOCAL_MACHINE\Software\EventSystemHKEY_LOCAL_MACHINE\Software\RPC3.关于WOW64的介绍:硬件本身具有32位兼容性模式,可以处理IA-32指令的实际执行,而WOW层处理诸如在32位和64位模式之间切换处理器以及模拟32位系统的事务。例如,32位和64位程序具有不同的注册表配置单元。还有一个用于32位二进制文件的不同的系统目录。64位二进制文件仍然使用System32目录,因此,当32位应用程序安装到系统中时,WOW层会确保将32位二进制文件置于一个新的目录SysWOW64中。这是通过如下方式实现的:根据应用程序是否运行在WOW下,截获对API的调用(如GetSystemDirectory)并返回适当的目录。相同的问题可能会存在于注册表中。因为32位和64位的COM服务器都可以安装在系统上,并位于相同的类标识符(CLSID)下,因此WOW层需要将对注册表的调用重定向到适当的32位或64位配置单元中。WOW层也会处理注册表中某些区域之间的镜像更改,以便使其更简单地支持32位和64位代码之间的交互操作。WOW64非常重要,因为当不关注性能和可伸缩性的问题时,它使您可以利用大多数现有的32位代码。它是两种方法的最佳结合。您可以将您的服务迁移到64位,同时将Microsoft管理控制台(MMC)配置管理单元保留为32位。Windows64位版本包括MMC的32位和64位的版本。当选择保留管理工具为32位时,进程间的通讯可能会遇到某些问题,但是只要接口设计正确,诸如远程过程调用(RPC)的协议应该可以在32位和64位进程之间运行。有关WOW64的另外一点需要牢记:它并不是为要求高性能的应用程序而设计的。至少,WOW64子系统需要将32位参数扩展到64位,并且需要将64位的返回值截断为32位。在最糟糕的情况下,WOW64子系统将需要进行内核调用,涉及到的不仅仅是到内核的转换,还有从处理器的32位兼容性模式到其本机64位模式的转换。在WOW64下运行时,应用程序将无法妥当地进行调整。对于那些您要将其保留为32位的应用程序而言,请在WOW64下测试它们。如果性能不能满足您的期望,您需要考虑将应用程序迁移到64位。WOW64是在用户模式下实现的,作为ntdll.dll和内核之间的层。WOW64及其支持的一些DLL仅仅是可以加载到32位进程中的64位的DLL。对于所有其他情况,进程保持为纯进程。32位的进程无法加载64位的DLL,反之亦然。看来上面的你也许就比较清楚了吧。一般程序就不需要什么移植,但是如果牵涉到驱动方面的东西,比如安装驱动等,那么这些是需要移植的。因为驱动是安装到内核来进行运行的,所以32位的驱动是不行的。注:二.使用VisualC++进行x64开发Win64和x64CPU体系结构的优点是:它们与其前任完全不同,但不需要很长的学习过程。尽管开发人员认为迁移到x64只是一个重新编译的过程,但事实是我们仍然要在调试器中花费很多时间。尽管可以使用VisualStudio®2005之前的Microsoft®C++编译器编写x64代码,但这在IDE中是一项沉闷的体验。因此,在本文中,我假定您使用的是VisualStudio2005,并选择在默认安装中未启用的x64工具。我还假定您在C++中拥有要为x86和x64平台构建的现有Win32用户模式项目。针对x64构建的第一步是创建64位生成配置。作为一个优秀的VisualStudio用户,您应该已经知道项目在默认情况下有两种配置:Debug和Retail。这里,您只需创建另外两个配置:x64形态下的Debug和Retail。首先,加载现有项目/解决方案。在Build菜单上,选择ConfigurationManager。在ConfigurationManager对话框中,从Activesolutionplatform下拉菜单中选择New(参见图7)。现在,您应该看到另一个标题为NewSolutionPlatform的对话框。图7创建新的生成配置选择x64作为您的新平台(参见图8),并将另一个配置保留为默认状态;然后单击OK。就这么简单!现在,您应该拥有四个可能的生成配置:Win32Debug、Win32Retail、x64Debug和x64Retail。使用ConfigurationManager,您可以轻松地在它们之间切换。现在,我们看一下您的代码与x64的兼容性。将x64Debug配置设为默认值,然后生成项目。除非代码不重要,否则可能会收到一些不会在Win32配置中发生的编译器错误。除非您已经完全摒弃了编写可移植C++代码的所有原则,否则修正这些问题以使代码能够随时用于Win32和x64相对比较轻松,而无需大量的条件编译代码。图8选择生成平台三.使代码与Win64兼容将Win32代码转换为x64,所需的最重要的工作可能是确保类型定义正确。还记得先前讨论的Win64类型系统吗?通过使用Windowstypedef类型而非C++编译器的本机类型(int、long等),Windows头使得编写干净的Win32x64代码很轻松。您应该在自己的代码中继续保持这一点。例如,如果Windows将一个HWND传递给您,请不要仅仅为了方便就将其存储在FARPROC中。升级完许多代码之后,我看到的最常见而简单的错误可能就是:假定指针值可以存储或传递到32位类型(如int和long)甚至DWORD中。Win32和Win64中的指针长度视需要而不同,而整数类型长度保持不变。但是,让编译器不允许指针存储在整数类型中也是不现实的。这是一个根深蒂固的C++习惯。解救方法是Windows头中定义的_PTR类型。DWORD_PTR、INT_PTR和LONG_PTR之类的类型可让您声明整数类型的变量,并且这些变量始终足够长以便在目标平台上存储指针。例如,定义为DWORD_PTR类型的变量在针对Win32编译时是32位整数,在针对Win64编译时是64位整数。经过实践,我已经习惯了声明类型以询问这里是否需要DWORD或者实际是指DWORD_PTR吗?。正如您期望的,可能有机会明确指定整数类型需要多少字节。定义DWORD_PTR及其友元的同一头文件(Basetsd.h)还可以定义特定长度的整数,如INT32、INT64、INT16、UINT32和DWORD64。与类型大小差异相关的另一个问题是printf和sprintf格式化。我对于在过去使用%X或%08X格式化指针值感到懊悔万分,并且在x64系统上运行该代码时还遇到了阻碍。正确的方法是使用%p,%p可以在目标平台上自动考虑指针大小。此外,对于与大小相关的类型,printf和sprintf还具有I前缀。例如,您可能使用%Iu来打印UINT_PTR变量。同样,如果您知道该变量始终是64位标记值,则可以使用%I64d。在清除了无法用于Win64的类型定义所导致的错误之后,可能还有只能在x86模式下运行的代码。或者,您可能需要编写函数的