【问题标题】:How does COM work?COM 是如何工作的?
【发布时间】:2015-11-10 08:54:30
【问题描述】:

我有一个据称是 COM 对象的 dll。我试图了解当 dll 中没有可用的导出函数时,CLR 究竟如何能够确定调用哪个函数(我使用依赖项进行了检查)。

  [Guid("DEADBEEF....")]
  [TypeLibType(...)]
  [ComImport]
  public interface ISomething
  {
    [DispId(1)]
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    [return: MarshalAs(UnmanagedType.IDispatch)]
    object DoSomething([MarshalAs(UnmanagedType.IDispatch), In] object something);

}

在这里,我检查了 MSIL,没有关于地址或函数名称的信息,或者它所在的偏移量。

此外,似乎没有关于对象如何布局以便传递其 vtable 指针等的信息。

这是什么魔法?

【问题讨论】:

    标签: c# windows com clr


    【解决方案1】:

    从(非托管)代码中,可以在与 COM 对象关联的“类型库”文件上使用 LoadTypeLib/LoadTypeLibEx。很常见的是,为 COM 对象本身注册的 EXE 或 DLL(但它也可以是独立的 TLB 文件、外部类型库等)。 LoadTypeLib 的文档在https://msdn.microsoft.com/en-us/library/windows/desktop/ms221027(v=vs.85).aspx 有进一步的指示。

    一旦获得ITypeLib/ITypeLib2类型库接口,它就会提供所有COM对象信息,包括接口、vtable布局、原型等。完整文档在https://msdn.microsoft.com/en-us/library/windows/desktop/ms221549(v=vs.85).aspx

    LoadTypeLib 的一个实际应用示例是随大多数版本的 Visual Studio 提供的 OLE/COM 对象查看器,它基本上可以将给定的类型库反编译回 IDL。我不能发布超过 2 个 URL,但请查找 https-//msdn.microsoft.com/en-us/library/d0kh9f4c.aspx。

    在托管代码中,编译器透明地执行类型库的导入,尽管在幕后它所做的工作与 OLE/COM 查看器基本相同,另外还添加了必要的托管包装器。有关详细信息,请参阅 https-//msdn.microsoft.com/en-us/library/xwzy44e4(v=vs.110).aspx。

    【讨论】:

    • 谢谢,这在理论上是否可以(甚至作为一种 hack)我可以生成等效的 MSIL,在没有运行时帮助的情况下调用这些东西? IE。我可以通过某种机制将 COM 调用转换为简单的 P/Invokes,即使是手动的
    • 理论上,我猜 unsafe 和 P/Invoke 的某种组合可以复制几乎任何 C 代码,包括 support.microsoft.com/en-us/kb/181473 的 OLE-from-C 示例。所以,是的,从技术上讲,你可以。不过,不知道你为什么会考虑这样做。您说“没有运行时帮助”,但也将您的问题标记为 C#/CLR。该框架已经加载了所有 COM 运行时支持,因此使用它不会有任何损失/开销(但如果使用它会很痛苦)。
    • 这是一个绝妙的主意,显然 COM 可以从 C 中调用,因此这是代码中的自然入口点。非常感谢,你让我很开心。
    猜你喜欢
    • 1970-01-01
    • 2012-04-06
    • 2017-10-14
    • 1970-01-01
    • 2017-12-06
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多