.NET Framework


在 64 位元 Windows 下的 .NET Framework 有分 32 位元和 64 位元版本,在 %SystemRoot%\Microsoft.NET 資料夾下,你可以看到 Framework (32 位元版) 和 Framework64 (64 位元版) 這兩個資料夾:

由於從 .NET Framework 2.0 開始才有 64 位元版,因此你可以看到 v1.0 和 v1.1 並不會有 64 位元版本。

.NET 的 Global Assembly Cache (GAC) 在 64 位元 Windows 上也分成三種格式 (32 位元、64 位元、MSIL 格式):

不論是 32 位元版 .NET Framework 還是 32 位元版 GAC,在 64 位元 Windows 上都是在 WOW64 環境上執行。

那麼 .NET 應用程式究竟會使用 32 位元還是 64 位元的 .NET Framework 和 GAC 呢? 這就要看當初的 .NET 應用程式是如何編譯的,在 .NET 編譯時可以指定平台目標為 AnyCPU, x86, x64, Itanium,如下圖 (VS2010):

如果使用 x86 選項編譯出來的 .NET 程式,就是 32 位元的應用程式,就會在WOW64 上跑,也就會使用 32 位元的 .NET Framework、32 位元 GAC 中的 32 位元元件,那麼在這個應用程式中就絕對不能使用 64 位元的元件、64 位元的 API 呼叫。

如果使用 x64 或 Itanium 選項編譯出來的 .NET 程式,就是 64 位元的應用程式,也就會使用 64 位元的 .NET Framework、64 位元 GAC 中的 64 位元元件,那麼在這個應用程式中就絕對不能使用 32 位元的元件、32 位元的 API 呼叫。

使用 AnyCPU (MSIL 格式) 編譯出來的 .NET 程式是屬於中性的 .NET 程式,可以同時在 64 位元平台和 32 位元平台上執行,例如前面提到的 IIS7 中,AnyCPU 編譯出來的 ASP.NET 程式就可以在 w3wp.exe 或 w3wp.exe *32 上執行。

如果你的 .NET 應用程式是所謂的 safe code,也就是程式中只用到 .NET 內建的功能、不呼叫外部非 .NET 的元件或 API、也不使用指標,那麼這樣的應用程式是可以直接拿到 64 位元平台上執行的。

但是如果您的 .NET 應用程式是 unsafe code,那麼就必須逐一測試每一個不相容的地方,例如以下 unsafe 的 C# 副程式:

public unsafe int UnsafeFn() {

   IntPtr * inputBuffer = sampleDLL.GetDataBuffer();

   IntPtr * ptr = inputBuffer;

   int   result = 0;



   for ( int idx = 0; idx < 100; idx ++ ) {

      result = result + ((int) *ptr);

      ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );

   }

   return result;

}

由於在 32 位元和 64 位元上的 int 大小是不一樣的,所以在做指標操作時,以下這一行就會出現問題:

ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );

因此可以改成:

ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( IntPtr ) );

這樣子不論是在 32 位元還是 64 位元環境下就都可以正常運行了。

同樣的問題也會發生在物件序列化 (serilization) 與反序列化上,如果使用 32 位元程式序列化 32 位元物件,再交給 64 位元程式反序列化為 64 位元物件,那麼反序列化就會出現問題,原因就出在 int 在不同位元數的平台上大小是不一樣的。

如果你想在 .NET 程式中辨認目前的作業系統是在 32 位元還是 64 位元平台上,可以直接由 System.IntPtr.Size 的值來判斷,如果要判斷所要載入的 .NET 組件是被編譯成那一個平台 ( x86, x64, ia64, AnyCPU ),可以使用 System.Reflection.Module.GetPEKind 方法:

public void GetPEKind(

    out PortableExecutableKinds peKind,

    out ImageFileMachine machine

)

回傳的第一個參數值:

成員名稱 說明
NotAPortableExecutableImage 此檔案並非使用可攜式執行檔 (PE) 格式。
ILOnly 可執行檔僅包含 Microsoft Intermediate Language (MSIL),因此相對於 32 位元或 64 位元平台而言是中性的。
Required32Bit 可執行檔可以在 32 位元的平台上執行,也可以在 64 位元平台的 32 位元 Windows on Windows (WOW) 環境下執行。
PE32Plus 可執行檔需要 64 位元的平台。
Unmanaged32Bit 可執行檔包含純 Unmanaged 程式碼。

回傳的第二個參數值:

成員名稱 說明
I386 以 32 位元的 Intel 處理器為目標。
IA64 以 64 位元的 Intel 處理器為目標。
AMD64 以 64 位元的 AMD 處理器為目標。

 

返回上一頁 >