1. 程式人生 > >C/C++32位程式移植到64位作業系統(轉)

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