【问题标题】:How do you find a COM's interfaces without typelib?你如何找到没有 typelib 的 COM 接口?
【发布时间】:2011-01-22 20:34:18
【问题描述】:

即使 TypeLib 完全为空,是否可以找到通常使用组件对象模型 (COM) TypeLib 注册的所有接口(类、参数等)?如果是这样,你会怎么做?我相信另一个术语是“匿名 COM”。我确信此 COM 存在可访问的接口,因为我有一个应用程序正在使用 TypeLib 中未列出的类。

【问题讨论】:

    标签: reflection com activex typelib


    【解决方案1】:

    如果类型库为空,则无法在 COM 库中找到有关类型的信息。

    您需要至少类型库中的一个 coclass 条目来找到 IUnknown 的实现。

    如果有,那么您实际上可以创建该类的实例,然后在 IUnknown 上调用 QueryInterface 以实现 IDispatch 实现(如果存在)。

    如果存在 IDispatch 接口,则可以调用 GetTypeInfo 以获取有关已实现接口的信息。

    如果您需要对 IDispatch 进行后期绑定调用,则需要调用 Invoke method

    请注意,您提到了类型库,但进程内 COM 服务器通常将类型库嵌入到 dll 中,该 dll 是库中表示的类型的实现。你确定你也没有检查过吗?或者你确定你有类型库并且它确实是空白的?

    如果类型库确实是空白并且 dll 中不包含它,那么从其他客户端针对它编译的意义上说,类型库完全有可能是“私有的”。 COM 在运行时不一定需要类型库。公开IClassFactory interface 实现的模式是导出具有众所周知签名的标准DLL 函数。

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

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

    它对您没有帮助,但可以解释为什么您看到的类型库中没有任何信息,同时看到其他客户端使用该库。

    【讨论】:

    • 感谢您的快速回答,我将不得不做更多的挖掘工作。但是是的,我确信 TypeLib 是不完整的,因为我有一个程序正在访问 COM 中不在 TypeLib 中的类。
    • @The Rook:我已经更新了我的答案,以反映您可能会看到这种行为的原因。
    【解决方案2】:

    在 COM 编程中不使用类型库是相当普遍的。任何脚本语言都会这样做,它使用 IDispatch 在运行时发现支持的方法和属性。 IDispatch::GetIDsOfNames() 或 IDispatch::GetTypeInfo() 让球滚动起来。这称为后期绑定。它很慢,但这在脚本语言中并不重要。

    另一种标准方法是通过 MIDL 从描述接口和 coclass 的 .idl 文件生成的头文件。您会在 Windows SDK 包含目录中找到其中的许多内容,例如 mshtml.h。但这仅适用于非托管 C/C++ 代码。

    在 C# 等托管语言中使用没有类型库的 COM 是困难的,但并非不可能。 VB.NET 是更好的语言,它支持开箱即用的后期绑定。 C# 在 4.0 版本到来时会变得更好,它有一个新的“动态”关键字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-17
      • 2014-06-15
      • 1970-01-01
      • 2020-07-28
      • 2014-03-07
      • 2015-10-13
      • 2013-05-21
      • 2019-04-12
      相关资源
      最近更新 更多