C/C++32位程序移植到64位操作系统(转)

1.  32位平台与64位平台

平台的定义

计算机系统是由硬件与软件两部分组成的。所谓平台也就是指硬件与相应的系统软件(包括操作系统、编译器和与开发环境有关的应用程序(如数据库))。

 64位硬件体系结构是指:

(1).能处理64位数据.---即CPU可以将64位数据作为基本单元进行处理(只需一次操作就可处理),”字长”是64位的,即存储单元是64位的.(说明:32位平台的存储单元是32位的)这导致结构成员的一种以8字节为边界的填充,即第一个成员即使不足一个8字节的基本存储单元,那么仍占用一个基本存储单元,而整个结构占用的存储空间也是8字节的倍数.

(2).能产生64位地址.----包括有效地址和物理地址.注意:虚地址概念并不是由处理器体系结构说明的,它是由AIX的VMM(虚地址存储管理器)说明的.它规定了应用程序可访问的内存空间的大小.一般来说,虚地址可以与有效地址或物理地址不同.

相应地,32位硬件体系结构是指:

(1).能将32位数据作为基本数据单元进行处理

;(2).最多只能产生32位地址(包括有效地址和物理地址).

下列操作可从64位寄存器中得到好处:

(1).64位长的串;

(2).64位寄存器上的移位操作;

(3).64位的整数和指针运算;

(4).串或大数据的拷贝. 

硬件部分主要是指其字长-----CPU能作为基本数据单元处理的二进制数据的位数。如32位机器其CPU能在一条指令内处理32位数据,它不能在一条指令内处理64位数据,它必须将64位数据分为两个32位数据进行处理;而64位机器其CPU则能在一条指令内处理64位数据,它不需象32位机器一样,将64位数据拆分为两个32位数据进行处理。

 32位平台是指其硬件体系结构是32位的,而且其操作系统、编译器等系统软也只能支持件也只能支持件32位程序.   

64位平台是指其硬件体系结构是64位的,而且其操作系统、编译器等也能支持64位程序.因而,64位平台能充分利用其64位硬件的性能,使得一些应用程序能从中得到性能的改善.

2.  如何识别程序为32位/64位

使用vs2010下的工具Visual Studio x64兼容工具命令提示来检测。在命令行中输入

dumpbin /headers +需检测的exe的绝对路径,

32位程序如下图所示:


64位程序如下图所示:

 

 

3.  应用程序移植

3.1   数据类型

 

Data Type

LP32(bits)

LP64(bits)

char

8

8

short

16

16

int

32

32

long long

64

64

long

32

64

pointer

32

64


3.2 API
    在编写32位64位兼容代码时要注意一个问题,有些API只有在64位系统中才存在(虽然目前这种API只大量存在于IA64),所以使用这些API时要注意条件编译(_M_AMD64)。
另外有两个重要的API,IsWow64Process和GetNativeSystemInfo。它们可以帮助32位应用程序来判断是否运行于64位系统(GetSystemInfo在32位进程中只会看到32位系统的功能)。但是在比较早的没有64位版本的系统中(比如Windows2000),这些API是不存在的。所以使用它们时要用动态加载的方式(LoadLibrary,GetProcAddress),如果加载失败也可以认为运行于32位系统。
3.3. 文件系统重定向
   
为实现WOW,64位Windows中的%windir%\System32文件夹会被重定向。64位进程对System32的引用会访问真实的System32目录,32位进程引用System32会被重定向到其它目录(GetSystemWow64Directory会得到这个目录)。
可以使用Wow64DisableWow64FsRedirection,Wow64EnableWow64FsRedirection, 和Wow64RevertWow64FsRedirection三个函数来打开或者关闭文件系统重定向。例如32位进行可以通过关闭重定向来访问真实System32目录,64位进程可以通过打开重定向来访问System32目录的32位映像。
但是以下一些目录是不会被重定向的:
%windir%\system32\catroot
%windir%\system32\catroot2
%windir%\system32\drivers\etc
%windir%\system32\logfiles
%windir%\system32\spool
3.4. 注册表重定向
  
与文件系统重定向相似,以下注册表项也会被重定向。
HKEY_LOCAL_MACHINE\Software
HKEY_USERS\*\Software\Classes
HKEY_USERS\*_Classes
32位进程想要访问64位注册表,64位进程想要访问32位注册表,需调用RegEnableReflectionKey和RegDisableReflectionKey关闭与开启注册表重定向,使用RegOpenKeyEx并通过设置samDesired 的KEY_WOW64_32KEY和KEY_WOW64_64KEY标志位来打开想要打开的注册表项。

32位程序访问64位注册表,C++代码示例如下:

#define KEY_WOW64_64KEY 256

#define KEY_WOW64_32KEY 512

typedef bool (__stdcall *RegEnableReflectionKey )(HKEY);

typedef bool (__stdcall *RegDisableReflectionKey)(HKEY);

HINSTANCE libInst = LoadLibrary("Advapi32.dll");

    if (!libInst) returnfalse; //Couldn't load library

    RegEnableReflectionKeyEnableReflectionKey=(RegEnableReflectionKey)GetProcAddress(libInst,"RegEnableReflectionKey");

    RegDisableReflectionKeyDisableReflectionKey=(RegDisableReflectionKey)GetProcAddress(libInst,"RegDisableReflectionKey");

    if(DisableReflectionKey)

    {

        DisableReflectionKey(p_hKey);

    }

#define KEY_WOW64_64KEY 256

#define KEY_WOW64_32KEY 512

::RegOpenKeyEx(p_hKey, p_pSubKey, NULL, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);

if(EnableReflectionKey)

        {

            EnableReflectionKey(hkey);

        }


3.5. 进程交互

32位安装包脚本若需调用64位进程,需加上Flags: 64bit。
  
32位进程无法调用64位动态库,64位系统无法调用32位动态库。但是32位进程可以启动64位进程,64位进程可以启动32位进程。
如果32位程序一定要访问64位动态库,而不想移植到到64位,可以通过启动一个64位进程对64位动态库进行调用,并通过进程间通信技术来实现数据传递。
一些系统API在64位进程中才会起作用(比如使用SetupDiCallClassInstaller改变设备状态),可以通过启动64位进程来调用这些API。

转自:http://wenku.baidu.com/link?url=NtpRZQ-6SFkgjCSJTdmnEVlRO233YiKx0Ukvh0HZcu3zSDsUQQXCK2g-KoBeld-s-t46VNsrRPh3O0bAqmwkWuv0Pc_Y4Nvm2B_pk-gZZ3K

没有更多推荐了,返回首页