我最近升級了一個c#windows服務以運行64位.net進程。通常情況下,這將是微不足道的,但系統使用C++編寫的32位DLL。它不是一個將此DLL轉換爲64位的選項,因此我將DLL封裝在單獨的32位.net進程中,並通過遠程處理暴露了.net接口。可以在Windows上將32位DLL加載到64位進程中嗎?
這是一個相當可靠的解決方案,但我寧願將系統作爲單個進程運行。有什麼辦法可以將我的32位DLL加載到64位進程中並直接訪問它(也許通過某種thunking層)?
我最近升級了一個c#windows服務以運行64位.net進程。通常情況下,這將是微不足道的,但系統使用C++編寫的32位DLL。它不是一個將此DLL轉換爲64位的選項,因此我將DLL封裝在單獨的32位.net進程中,並通過遠程處理暴露了.net接口。可以在Windows上將32位DLL加載到64位進程中嗎?
這是一個相當可靠的解決方案,但我寧願將系統作爲單個進程運行。有什麼辦法可以將我的32位DLL加載到64位進程中並直接訪問它(也許通過某種thunking層)?
不,你不能。
16位和32位Windows均位於32位線性地址空間中。術語16和32指的是相對於選擇器的偏移大小。
...
首先,注意一個全尺寸的16位指針和一個32位平面指針具有相同的尺寸。值0x0123:0x467需要32位,而哇,32位指針也是如此。這意味着包含指針的數據結構在16位和32位對應數據之間不會改變大小。非常方便的巧合。
這兩個觀察結果都不適用於32位到64位thunk。指針的大小發生了變化,這意味着將32位結構轉換爲64位結構或反過來會改變結構的大小。 64位地址空間比32位地址空間大40億倍。如果在偏移量爲0x000006fb`的64位地址空間中存在某些內存,則32位代碼將無法訪問它。這不像你可以建立一個臨時地址窗口,因爲32位平面代碼不知道這些臨時地址窗口;他們放棄了選擇器,記得嗎?
http://blogs.msdn.com/oldnewthing/archive/2008/10/20/9006720.aspx
如果你的.NET應用程序是在IIS中運行一個網站,你可以繞過它。
在64位機器上的IIS上運行的ASP.NET網頁將由64位版本的w3wp.exe進程託管,如果您的網頁使用32位dll,則您的網站將失敗。
但是,在IIS中,您可以進入運行該站點的應用程序池的高級設置,並將「啓用32位應用程序」更改爲true。
因此,它仍然無法在64位進程中運行32位dll,而是將它作爲32位進程運行w3wp.exe。
該問題指出該進程是Windows服務而不是ASP.NET網站。更重要的是,您所描述的IIS設置實際上實現了與問題試圖避免的相同的解決方案。 – 2011-12-14 14:30:53