64 到 32 位互操作 - 如何?

Posted

技术标签:

【中文标题】64 到 32 位互操作 - 如何?【英文标题】:64 to 32 bit Interop - how? 【发布时间】:2010-10-26 21:11:19 【问题描述】:

我需要将一些遗留的 32 位代码(我没有源代码)集成到一个项目中,以便可以从 64 位 .NET 程序集调用它。原始代码在 DLL 中实现为 32 位 COM 对象。 Windows 不允许从 64 位对象直接调用到 32 位对象,因此我正在寻找有关如何处理这种情况的灵感。

如何从 64 位 .NET 程序集访问旧的 32 位 COM 对象?

更新:我们发现 COM 组件本身是一些 ANSI C 的包装器,我们为其找到了原始源代码。我们能够在 Visual Studio 中将其编译为原生 64 位 dll,并将其导入 .NET - 抱歉移动了球门柱!

【问题讨论】:

评论,因为我还没有这样做,但您需要确保将 COM 对象作为进程外服务器运行。如果您将其加载为进程内,它将以 64 位运行,这将失败。 【参考方案1】:

最好的方法是制作一个包含 32 位 DLL 的进程外 COM 服务器。然后您可以从 64 位代码中调用它。

Here is an explanation的基本概念。

【讨论】:

我稍微移动了球门柱,因为我们发现了一些导致我们找到不同解决方案的源代码。我接受这个答案,因为我认为它最能回答原始问题和有用的阅读材料的链接。【参考方案2】:

您需要做的是创建两个与 IPC 通信的进程。这样,一个可以是 32 位的,一个可以是 64 位的。您需要创建一个 32 程序,该程序与 COM 对象链接并通过一些 IPC 机制(例如命名管道)公开其 API。这样您的 .NET 程序就可以从另一个进程访问它。

【讨论】:

这种方法可行,但如果您已经在使用 COM,为什么要切换到命名管道而不是仅仅使用 COM 互操作? @Reed Copsey:哦,是的,当然你可以将它用于 COM。但我的方法更笼统;它也适用于普通库。 我想到了使用 WCF 来使用命名管道进行 IPC。唯一的问题是,管道的两端需要看到相同的接口定义,它必须在 32 位程序集中。当您尝试运行它时,整个事情都会爆炸。【参考方案3】:

看看这个blog post。您可以使用运行时可调用包装器从 64 位 .NET 应用程序引用 32 位 COM 程序集。简短的版本如下...

    使用 tlbimp.exe 创建 64 位 Runtime Callable Wrapper:

    tlbimp.exe foo.dll /machine:x64 /out:Interop.Foo.dll

    如果您还没有注册 COM 程序集(不是 RCW):

    regsvr32.exe foo.dll

    从您的应用程序中引用 RCW(例如 Interop.Foo.dll)。将您的构建配置更改为 x64,然后开始吧。

【讨论】:

这不是原始问题的解决方案。

以上是关于64 到 32 位互操作 - 如何?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .net 中对 MemoryMappedFiles 使用 x64 互锁操作

Visual Studio 2010 64 位 COM 互操作问题

WPF与Win32互操作

如何强制 MSBuild 编译为 32 位模式?

映射平台特定的互操作类型

将 C# 函数指针传递到 C++/CLI 互操作 dll