从 64 位进程调用 32 位代码
Posted
技术标签:
【中文标题】从 64 位进程调用 32 位代码【英文标题】:Calling 32bit Code from 64bit Process 【发布时间】:2010-09-12 19:24:37 【问题描述】:我有一个应用程序正在尝试从 32 位迁移到 64 位。它是 .NET,使用 x64 标志编译。但是,我们有大量用 FORTRAN 90 编写的 DLL,为 32 位编译。 FORTRAN DLL 中的函数相当简单:你把数据放进去,你把数据拉出来;没有任何状态。我们也不会花很多时间在那里,总共大概 3%,但它执行的计算逻辑是无价的。
我能否以某种方式从 64 位代码调用 32 位 DLL? MSDN 建议我不能,期间。我做了一些简单的黑客攻击并验证了这一点。一切都会抛出一个无效的入口点异常。到目前为止,我发现的唯一可能的解决方案是为所有 32 位 DLL 函数创建 COM+ 包装器,并从 64 位进程调用 COM。这似乎很让人头疼。我们也可以在 WoW 仿真中运行该过程,但内存上限不会增加,上限约为 1.6gb。
还有其他方法可以从 64 位 CLR 进程调用 32 位 DLL 吗?
【问题讨论】:
Access x86 COM from x64 .NET的可能重复 【参考方案1】:您需要将 32 位 dll 加载到单独的 32 位进程中,并让您的 64 位进程通过进程间通信与其进行通信。我认为没有任何方法可以将 32 位 dll 加载到 64 位进程中。
这里有一篇不错的文章:
Accessing 32-bit DLLs from 64-bit code
【讨论】:
这就是我所描述的 64 位 -> COM -> 32 位。在阅读了那篇文章并尝试让示例工作后,我决定有 got 是一种更好的方法。至少我希望如此。 约翰的回答是正确的。没有办法将 32 位和 64 位模块混合在一个进程中。您需要开始第二个过程。另请参阅我的答案:***.com/questions/6523075/… 您不一定需要使用 COM+ 包装器,但您确实需要使用 32 位进程。 这是正确的。见微软页面:msdn.microsoft.com/en-us/library/windows/desktop/… Windows 代理进程似乎是一个很好的潜在方法:***.com/a/359389/3195477【参考方案2】:您需要将您的可执行进程编写为 32 位进程(相对于任何 CPU 或 x64),以便它们可以通过 WoW32 for Vista 加载。这将以 32 位仿真模式加载它们,并且您不会遇到入口点问题。您可以将库保留在 AnyCPU 模式,但您的可执行文件必须编译为 x86。
【讨论】:
听起来他们已经考虑过了,但需要增加 64 位提供的内存上限 有一半是正确的:如果您将 32 位进程编译为 x86,则它们可以在 x64 机器上运行。但是,如果您的可执行文件是 x86 并且您的库是 AnyCPU - 即时编译器将从它们中生成 x64 代码,这使得它们与(32 位)可执行文件不兼容。因此,包括程序集在内的所有内容必须是 x86 或 AnyCPU。【参考方案3】:如果您不想重新编译现有的 dll,John 的回答是正确的;但是,这也可能是您的选择。
我们的团队目前正在将 x86 FORTRAN 代码迁移到 x64 以增加内存上限。
【讨论】:
只要您没有任何需要添加作为参考的 32 位 3rd 方程序集(没有源代码),此方法就可以使用...以上是关于从 64 位进程调用 32 位代码的主要内容,如果未能解决你的问题,请参考以下文章
当 Delphi 32 位应用程序的相同代码工作时,从 Delphi 64 位应用程序调用 MAPI 电子邮件不起作用?