[.NET Framework]WOW64的介紹

[.NET Framework]WOW64的介紹

前幾天發表了一篇[.NET Framework]64位元呼叫32位元元件文章後,想說要再把當初解決問題的完整思路PO出來跟大家分享一下,這個分享主要會分兩篇來說明,在說明我的做法前,我想有必要先好好的介紹一下32位元應用程式如何執行於64位元電腦上,我們先看看這篇微軟MSDN的說明文章:

Running 32-bit Applications

以下摘要幾段話:

WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows.

The system isolates 32-bit applications from 64-bit applications, which includes preventing file and registry collisions. Console, GUI, and service applications are supported. The system provides interoperability across the 32/64 boundary for scenarios such as cut and paste and COM. However, 32-bit processes cannot load 64-bit DLLs for execution, and 64-bit processes cannot load 32-bit DLLs for execution.

裡頭提到一個關鍵的詞WOW64,這是Windows-on-Windows 64-bit的縮寫,代表的是在64位元上模擬出一個32位元的執行環境,讓32位元的執行程式可以運行,但上頭這段話也同時點出了問題所在,32位元的處理緒不能載入64位元的dll,64位元的處理緒同樣不能載入32位元的dll。

 

WOW64的概念是什麼?我想大家可以參考微軟的Best Practices for WOW64,裡頭說的蠻詳細的,下面截取它的運作架構圖,該文件中同時有提到WOW64的限制與Windows on 64位元的一些變更,建議大家仔細的閱讀一下,回到正題我們來看看下面這張圖:image

一樣摘錄文件中的一段話:

When a 32-bit application runs, the native library loader starts first. It recognizes that the executable image is a 32-bit process and handles it in a special manner. The native loader sets up a WOW64 emulation environment for 32-bit processes and transfers control to the 32-bit loader (in the 32-bit Ntdll.dll).

The WOW64 emulation layer runs between the 32-bit application and the native (64‑bit) Ntdll.dll and translates the application’s calls to the 32-bit Ntdll.dll to calls to the 64-bit Ntdll.dll. Any return calls are similarly translated and passed to the 32-bit application.

WOW64的概念是透過WOW64 Emulation來進行32位元/64位元執行環境的溝通,它的概念像是在64位元電腦上另外起了一個子系統,概念或許跟VM有點類似。

以上大致解說了一下WOW64的概念,接著回到我們的正題了,前頭提到32-bit processes cannot load 64-bit DLLs for execution, and 64-bit processes cannot load 32-bit DLLs for execution.這句話是我們當初面臨的最大問題,以Windows Application來說,程式執行時的處理緒就是該應用程式的名稱,例如word.exe、iexplorer.exe....,當處理緒在執行時,需要直接叫用到任何dll,不管是前期繫結(加入參考)或者是晚期繫結(DllImport、LoadAssembly、CreateInstance…)這個dll都會被載入到應用程式的處理緒中,而只要執行緒的執行環境跟dll所需的不同,就會出現載入錯誤的問題,EX:BadImageException...

當時在網路上找了好久,後來找到這篇文章:Accessing 32-bit DLLs from 64-bit code

這篇文章有如我的指路明燈一般,裡頭提到,如果要在64位元的應用程式當初呼叫32位元的dll,可以透過Out-Of-Process的方式來進行,也就是說不要透過本身這個處理緒來完成dll的呼叫,而後來依此概念我就使用了.net remoting來作為我Out-Of-Process的媒介,這部分在下一篇中進行說明。

游舒帆 (gipi)

探索原力Co-founder,曾任TutorABC協理與鼎新電腦總監,並曾獲選兩屆微軟最有價值專家 ( MVP ),離開職場後創辦探索原力,致力於協助青少年培養面對未來的能力。認為教育與組織育才其實息息相關,都是在為未來儲備能量,2018年起成立為期一年的專題課程《職涯躍升的關鍵24堂課》,為培養台灣未來的領袖而努力。