在 64 位 .NET 应用程序中使用 32 位非托管 COM 服务器

Posted

技术标签:

【中文标题】在 64 位 .NET 应用程序中使用 32 位非托管 COM 服务器【英文标题】:Using a 32 bit unmanaged COM server in a 64 bit .NET application 【发布时间】:2011-10-04 22:16:43 【问题描述】:

我需要。

我做了一些研究,似乎找到了一个合适的解决方案:将 COM 服务器托管在 COM+ 服务器应用程序中。因此,该组件在专用(32 位)进程中激活,并通过 RPC 与 64 位进程通信。 (link)

为了测试上述内容,我创建了一个示例 COM 服务器并将其注册到 COM+ 应用程序中。它的界面是这样的:

interface ITestComObj: IUnknown

  HRESULT _stdcall Ping( void );
  HRESULT _stdcall Uppercase([in] LPSTR input, [out, retval] LPSTR * output );
;

然后我创建了一个简单的 .NET 控制台应用程序,它通过 COM 互操作调用这些方法。

首先我在 32 位 WinXP 上测试它,它运行良好。

然后我搬到了 64 位 Win7。第一次调用(无参数 Ping() 方法)成功,但第二次调用抛出异常(经过一段时间的等待):远程过程调用失败。 (HRESULT 异常:0x800706BE)。

我做了一些进一步的调查。我强制客户端进入 32 位进程(将其构建到 x86 目标平台)以查看是否有任何变化,但结果是一样的。但是,如果我切换到进程内激活(将 COM+ 应用程序类型更改为库应用程序),客户端就可以工作了。

显然,跨进程参数传递在 Win7 上出现了问题,但即使在谷歌上搜索了几个小时后我也找不到答案。

有什么想法吗?

【问题讨论】:

每个数组的大小是多少? 顺便说一句,你见过这个问题吗? ***.com/questions/3573523/… 【参考方案1】:

我认为问题可能出在字符串类型的编组中。我会尝试使用:

HRESULT _stdcall Uppercase([in] BSTR input, [out, retval] BSTR * output );

而不是

HRESULT _stdcall Uppercase([in] LPSTR input, [out, retval] LPSTR * output );

【讨论】:

【参考方案2】:

问题在于编组 - 互操作层无论出于何种原因都无法正确编组第二个调用参数。我建议你把签名改成arrays with size_is attribute。

【讨论】:

以上是关于在 64 位 .NET 应用程序中使用 32 位非托管 COM 服务器的主要内容,如果未能解决你的问题,请参考以下文章

如何使 .NET 可执行文件在 64 位操作系统上作为 32 位进程运行?

在 .NET 项目中同时引用 32 位和 64 位 dll 并单击一次 [重复]

在 64 位 .Net 应用程序中导入 32 位 dll

将 32 位 VB.Net 连接到 64 位 Access .ACCDB

在 C# DllImport 中使用 32 位或 64 位 dll

当使用 32 位版本的 MySQL 的 .net 连接器连接到 64 位版本的 MySQL 时,我得到“等待表元数据锁定”