34

我最近升级了 ac# windows 服务以作为 64 位 .net 进程运行。通常,这很简单,但系统使用了一个用 C++ 编写的 32 位 DLL。将此 DLL 转换为 64 位不是一个选项,因此我将 DLL 包装在一个单独的 32 位 .net 进程中,并通过远程处理公开了一个 .net 接口。

这是一个非常可靠的解决方案,但我更愿意将系统作为单个进程运行。有什么方法可以将我的 32 位 DLL 加载到 64 位进程中并直接访问它(可能通过某种 thunking 层)?

4

2 回答 2

26

不,你不能。

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

于 2008-10-22T10:29:47.957 回答
6

如果您的 .NET 应用程序是在 IIS 中运行的网站,您可以绕过它。

在 64 位机器上的 IIS 上运行的 ASP.NET 网页将由 64 位版本的 w3wp.exe 进程托管,如果您的网页使用 32 位 dll,您的网站将失败。

但是在 IIS 中,您可以进入运行该站点的应用程序池的高级设置,并将“启用 32 位应用程序”更改为 true。

所以它仍然无法在 64 位进程中运行 32 位 dll,而是将 w3wp.exe 作为 32 位进程运行。

于 2008-11-14T23:00:56.917 回答