从 x64 .NET 访问 x86 COM

Posted

技术标签:

【中文标题】从 x64 .NET 访问 x86 COM【英文标题】:Access x86 COM from x64 .NET 【发布时间】:2010-09-26 10:29:56 【问题描述】:

我有一个 x64 服务器,因为我的库被编译到 AnyCPU,所以在 x64 下运行。我们需要访问在 x86 下注册的 COM 组件。我对 COM 知之甚少,而且我的谷歌搜索无处可去。

问题:我可以为 COM 组件使用从 x64 回到 x86 的符号注册表链接吗?我是否也需要在 x64 下注册 COM 组件?我可以(这里有任何陈述......)吗?

谢谢。

【问题讨论】:

【参考方案1】:

如果一个组件运行 x64-native,它不能在进程中加载​​ 32 位 COM 服务器,因为它是错误的进程类型。有几种可能的解决方案:

    如果可以,构建一个 64 位版本的 COM 代码(它当然会在 64 位注册表中注册自己)。这是最简洁的解决方案,但如果您没有 COM 服务器的代码,则可能无法实现。

    将 .NET 组件运行为 32 位 x86,而不是 x64。我假设您已经考虑过并出于某种原因拒绝了这个。

    使用COM surrogate DLLhost.exe 在进程外托管COM 组件。这将使对 COM 服务器的调用慢得多(它们现在将是进程间 Windows 消息,而不是本机函数调用),但在其他方面是透明的(您不必做任何特别的事情)。

    如果服务器需要自定义代理存根而不是使用普通的 oleaut32 代理存根(但非常罕见),这可能不是一个选项,因为不会有 64 位版本的代理可用。只要能使用普通的OLE编组,register it for surrogate activation即可。

【讨论】:

#1 是不可能的,因为没有 x64 版本。 #2 违背了在 x64 上运行的目的。 #3 效果很好。在我们获得新版本的库之前,我们可以忍受这里的性能命中。感谢您的帮助。 @puetzk 在我的情况下,我使用的是作为另一个应用程序的一部分安装的第三方 dll。我无法控制大会。在这种情况下,如何使用 COM 代理功能?谢谢 @MeTitus 你必须自己添加注册表项,协调版本可能很棘手,但仍然可以这样做。 @puetzk 我最终选择了另一条路线。感谢您的回复。圣诞快乐。【参考方案2】:

我找到了这个解决方案,Dealing with Legacy 32-bit Components in 64-bit Windows 见文章: • 将项目类型从进程内转换为进程外 • 使用 COM+ 作为主机(这对我有用) • 使用 dllhost 作为代理主机

【讨论】:

谢谢。但是现在链接已经失效了。于是我搜索了webarchive发现文档是64-bit Insider Volume I, Issue 7-Dealing with Legacy 32-bit Components in 64-bit Windows【参考方案3】:

这是您的 COM 组件位于 COM 服务器中(即单独的进程),那么您无需执行任何特殊操作,因为 COM 子系统会将您的调用从 x64 应用远程远程到 X86 应用并再次返回。

如果您的组件是进程内 COM 组件,那么您将不得不重新考虑,因为 64 位进程不能使用 32 位进程内 COM 组件。您可以强制您的服务器在 x86 下运行,以便您可以访问组件(它们都是 32 位进程)。如果您不想这样做,则必须查看您正在使用的 COM 组件是否有 x64 位版本。

【讨论】:

以上是关于从 x64 .NET 访问 x86 COM的主要内容,如果未能解决你的问题,请参考以下文章

无法在 x86 上以 SSE 类型访问内存,但在 x64 上工作正常

Windows 64 位注册表与32 位注册表

如何在 x64 机器上从 nmake 访问 ProgramFiles 环境变量?

测试篇 c#读PE文件x86和x64

x86、x32 和 x64 架构之间的区别?

为啥编译为 x86 的 .NET EXE 会以 x64 运行?