.net 我可以将 32 位 DLL 加载到 Windows 上的 64 位进程中吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/225151/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I load a 32 bit DLL into a 64 bit process on Windows?
提问by Lee
I recently upgraded a c# windows service to run as a 64 bit .net process. Normally, this would be trivial, but the system makes use of a 32-bit DLL written in C++. It is not an option to convert this DLL to 64 bit, so I wrapped the DLL in a separate 32 bit .net process and exposed a .net interface via remoting.
我最近升级了 ac# windows 服务以作为 64 位 .net 进程运行。通常,这很简单,但系统使用了用 C++ 编写的 32 位 DLL。不能将此 DLL 转换为 64 位,因此我将 DLL 包装在单独的 32 位 .net 进程中,并通过远程处理公开了 .net 接口。
This is quite a reliable solution, but I would prefer to run the system as a single process. Is there any way I can load my 32 bit DLL into a 64 bit process and access it directly (perhaps through some sort of thunking layer)?
这是一个非常可靠的解决方案,但我更愿意将系统作为单个进程运行。有什么办法可以将我的 32 位 DLL 加载到 64 位进程中并直接访问它(也许通过某种 thunking 层)?
采纳答案by Jon Grant
No, you can't.
不,你不能。
Both 16-bit and 32-bit Windows lived in a 32-bit linear address space. The terms 16 and 32 refer to the size of the offset relative to the selector.
...
First, notice that a full-sized 16-bit pointer and a 32-bit flat pointer are the same size. The value 0x0123:0x467 requires 32 bits, and wow, so too does a 32-bit pointer. This means that data structures containing pointers do not change size between their 16-bit and 32-bit counterparts. A very handy coincidence.
Neither of these two observations holds true for 32-bit to 64-bit thunking. The size of the pointer has changed, which means that converting a 32-bit structure to a 64-bit structure and vice versa changes the size of the structure. And the 64-bit address space is four billion times larger than the 32-bit address space. If there is some memory in the 64-bit address space at offset 0x000006fb`01234567, 32-bit code will be unable to access it. It's not like you can build a temporary address window, because 32-bit flat code doesn't know about these temporary address windows; they abandoned selectors, remember?
16 位和 32 位 Windows 都生活在 32 位线性地址空间中。术语 16 和 32 指的是相对于选择器的偏移量的大小。
...
首先,请注意全尺寸 16 位指针和 32 位平面指针的大小相同。值 0x0123:0x467 需要 32 位,哇,32 位指针也是如此。这意味着包含指针的数据结构在 16 位和 32 位对应物之间不会改变大小。一个非常方便的巧合。
这两个观察结果都不适用于 32 位到 64 位转换。指针的大小发生了变化,这意味着将 32 位结构转换为 64 位结构,反之亦然会改变结构的大小。并且 64 位地址空间比 32 位地址空间大 40 亿倍。如果 64 位地址空间中偏移量 0x000006fb`01234567 处有一些内存,32 位代码将无法访问它。这不像你可以建立一个临时地址窗口,因为 32 位平面代码不知道这些临时地址窗口;他们放弃了选择器,记得吗?
http://blogs.msdn.com/oldnewthing/archive/2008/10/20/9006720.aspx
http://blogs.msdn.com/oldnewthing/archive/2008/10/20/9006720.aspx
回答by Frode Lillerud
If your .NET application is a website running in IIS you can circumvent it.
如果您的 .NET 应用程序是在 IIS 中运行的网站,您可以绕过它。
An ASP.NET webpage running on IIS on a 64-bit machine will be hosted by a 64-bit version of the w3wp.exe process, and if your webpage uses 32-bit dlls your site will fail.
在 64 位机器上的 IIS 上运行的 ASP.NET 网页将由 w3wp.exe 进程的 64 位版本托管,如果您的网页使用 32 位 dll,您的网站将失败。
However in IIS you can go into the Advanced Settings of the Application Pool running the site, and change "Enable 32-bit applications" to true.
但是,在 IIS 中,您可以进入运行站点的应用程序池的高级设置,并将“启用 32 位应用程序”更改为 true。
So it's still not able to run 32-bit dll inside 64-bit process, but rather it is running w3wp.exe as a 32-bit process instead.
因此,它仍然无法在 64 位进程中运行 32 位 dll,而是将 w3wp.exe 作为 32 位进程运行。

