如何在没有类型库的情况下查找COM接口?

7

即使TypeLib完全为空,是否有可能找到通常注册在Component Object Model(COM)TypeLib中的所有接口(类、参数等)?如果可以,您将如何进行操作?我相信另一个术语是“匿名COM”。我确定可访问此COM的接口存在,因为我有一个应用程序正在使用未列在TypeLib中的类。

2个回答

8
如果类型库为空,则无法找到有关COM库中类型的信息。
您需要在typelib中至少拥有一个coclass条目,才能找到IUnknown的实现。
如果您拥有该条目,则实际上可以创建类的实例,然后对IUnknown调用QueryInterface以获取IDispatch实现(如果存在)。
如果存在IDispatch接口,则可以调用GetTypeInfo以获取实现的接口信息。
如果需要对IDispatch进行后期绑定调用,则需要调用Invoke method
请注意,您提到了类型库,但在进程内COM服务器中,将类型库嵌入表示库中的实现dll是常见做法。您确定您没有检查过吗?或者您确定已经有了类型库并且它确实是空的吗?
如果类型库确实为空并且dll不包含它,那么类型库可能是“私有”的,也就是说其他客户端是针对它进行编译的。COM在运行时不一定需要类型库。公开IClassFactory接口实现的模式是导出具有众所周知签名的标准DLL函数。

您可以轻松调用LoadLibrary,然后调用GetProcAddress并将结果转换为IClassFactory。从那里开始,他们将使用他们所知道的私有GUID和IID(不是来自类型库)以及他们私下定义的COM接口,并从那里开始工作。

我能想到的唯一理由是某种形式的混淆和/或解决隐私/安全问题,只允许生产服务器批准的客户端调用它。

这对您没有帮助,但可能解释了为什么您看到一个没有信息的类型库,同时看到其他客户端使用该库。


谢谢您的快速回复,我需要再深入研究一下。但是我确信TypeLib不完整,因为我有一个程序正在访问COM中的一个类,而该类不在TypeLib中。 - rook
@The Rook:我已经更新了我的答案,以反映您可能看到这种行为的原因。 - casperOne

5
在COM编程中不使用类型库是相当普遍的。任何脚本语言都使用IDispatch在运行时发现支持的方法和属性。IDispatch :: GetIDsOfNames()或IDispatch :: GetTypeInfo()推动了这一进程。这被称为后期绑定。它很慢,但在脚本语言中并不重要。
另一种标准方法是通过由.idl文件生成的头文件来描述接口和coclass。您会在Windows SDK包含目录中找到许多这样的文件,例如mshtml.h。但这仅适用于非托管的C / C ++代码。
在像C#这样的托管语言中使用没有类型库的COM是困难的,但并非不可能。 VB.NET是更好的语言,它支持开箱即用的后期绑定。当版本4.0到来时,C#将变得更好,它有一个新的“dynamic”关键字。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接