从 TLB 导入的接口上的进程外 COM 服务器的 QueryInterface

Posted

技术标签:

【中文标题】从 TLB 导入的接口上的进程外 COM 服务器的 QueryInterface【英文标题】:QueryInterface of out-of-proc COM server on interface imported from TLB 【发布时间】:2011-05-18 11:39:21 【问题描述】:

我在 A.idl 文件中定义我的接口,我将其编译为 A.tlb

在 VS2005 ATL 项目“B”中,我在 B.idl 中使用 importlib(A.tlb),在 stdafx.h 中使用 #import“A.tlb”,并在 ATL COM 类中从 A.tlb 实现接口 IA。项目输出一个 B.dll 和一个 B.tlb

我将 B.tlb 添加到 C# 应用程序的引用中,并在代码中实例化 COM 对象。

如果我使用任何一个,实例化都不会出现问题

Type.GetTypeFromCLSID(); Activator.CreateInstance(...);

[DllImport("ole32.dll", ...)] CoCreateInstance(...)

两者都工作正常,对象实例化,我可以将其转换为定义在 A.tlb 中的 IA 接口(实际上是从 tlb 生成的 RCW)并调用其方法。仍然没有问题。

然后我使用 OLEView 使用默认的 DllHost.exe 代理启用 COM 对象激活。

COM 对象的实例化在代理项中(CoCreateInstance 中的参数 CLSCTX_LOCAL_SERVER)仍然没有问题,但是 当我尝试将对象强制转换为 A.tlb 中定义的 IA 接口时我收到 E_NOINTERFACE 和一条消息,说 QueryInterface 失败,因为“不支持此类接口”。

请帮忙。有什么问题?如果您需要任何其他信息,我会尽量提供。

【问题讨论】:

我尝试将所有 idl 代码从 A.idl(结构和接口定义)复制并粘贴到 B.idl,删除 #import "A.tlb" 瞧——我可以转换创建的对象使用 CoCreateInstance 到 IA 并毫无问题地使用它。这意味着该错误要么是 A.tlb 的编译方式,要么是我包含/导入 tlb 的方式,或者是 tlb 中接口的注册表项的方式。关于如何正确使用 TLB 中定义的接口的任何提示? 【参考方案1】:

您需要构建和注册代理/存根 DLL。跨进程边界编组接口所必需的。我找不到很好的 MSDN 页面,但它是 mentioned here。

【讨论】:

不幸的是,构建和注册 BPS(生成的代理/存根项目)没有帮助。我需要手动编辑 PS 项目中的任何内容吗? 通常不会。请确保所有内容都已正确注册。您必须在 HKCR\Interfaces 中查看您的接口 IID,并列出代理 CLSID。 SysInternals 的 ProcMon 将其可视化,您会看到 COM 访问注册表项以寻找代理。 谢谢。最后,代理/存根 dll 的构建和注册解决了我的问题。一篇相当不错的 msdn 文章在这里 msdn.microsoft.com/en-us/library/ms688707 加上我不得不谷歌解决编译过程中出现的一些小错误。

以上是关于从 TLB 导入的接口上的进程外 COM 服务器的 QueryInterface的主要内容,如果未能解决你的问题,请参考以下文章

如何加载 COM dll 模块并将其接口公开为进程外服务器

64 位托管进程:进程外 32 位 COM 服务器非默认接口不可用

.NET 进程外服务器的#import 问题

COM客户端连接COM服务器所需的文件是什么(进程外方案)?

Linux进程切换 TLB处理

“纯”调度接口编组