【问题标题】:How to define implementation of a COM coclass?如何定义 COM coclass 的实现?
【发布时间】:2011-06-28 15:33:11
【问题描述】:

我是 COM 新手,我在互联网上四处寻找如何在 C++ 中创建 COM 类(供 C# 使用)。我已经在 .idl 文件中看到了,我必须这样写:

[
object,
uuid(a93164ee-e6d4-44be-aa27-f00ce6972719),
helpstring("interface ITopologyQuery")
]

interface ITopologyQuery : IUnknown
{
  HRESULT LoadFile(BSTR completeFileName);

  HRESULT SetParameters(int above, int percentage);
}

[
  uuid(a958f2af-8b55-43c4-9fc3-c39d83fc1376)
]
library TopologyQueryLib
{
  [
    uuid(cc814992-31ec-4a1f-a41e-111ade27bdfe),
    helpstring("TopologyQuery class")
  ]
  coclass CTopologyQuery
  {
    [default] interface ITopologyQuery;
  };
}

现在我的问题是,您在哪里定义 CTopologyQuery 类?如果我将它定义为另一个文件中的常规 c++ 类,编译器会将我的类与接口正确链接吗? c++类代码如下(在.cpp文件中实现):

class CTopologyQuery : public ITopologyQuery
{
  public:

    __stdcall CTopologyQuery();

    //IUnknown interface 
    HRESULT __stdcall QueryInterface(REFIID riid, void **ppObj);
    ULONG   __stdcall AddRef();
    ULONG   __stdcall Release();

    //ITopologyQuery interface
    HRESULT __stdcall LoadTopologyFile(BSTR completeFileName);
    HRESULT __stdcall SetParameters(int above, int percentage);

  private:
};

现在,如果我将库部分放在 .idl 文件中,或者不这样做,它都会编译。我有点失落,因为这里有什么好处?我知道 coclass 定义应该为接口提供默认实现,但对我来说它看起来像一个没有方法的空类......

【问题讨论】:

  • 你读过Exposing COM Components to the .NET Framework (MSDN)。当我试图理解 .Net/COM 互操作时,这很有帮助。
  • 您在使用 ATL 吗? MFC?还是您全部手动完成?
  • @bdonlan:我正在使用 MFC,我想使用 ATL,但该向导对我不起作用(由于一个模糊的原因,当它启动时它会清除我的资源附加包含目录,然后给出我是一个 RC1015 错误)。所以我尝试手动完成(同时我尝试了解 COM 的工作原理)
  • 好的。这是EXE还是DLL?
  • 另外,对于 DLL,这是进程内服务器还是进程外服务器?

标签: c++ com coclass


【解决方案1】:

IDL(接口定义语言)部分以独立于语言的方式定义二进制接口,看起来很像 C++。

它通常用于构建二进制类型库,这是一个包含有关您的 COM 类信息的 DLL。您可以使用 Microsoft 的 COM/OLE 查看器来浏览现有的类型库。

对于非IDispatch COM 类的 C++ 使用,您不需要有关您的类的信息,因为 C++ 编译器需要知道的所有信息(至少)都在您的 C++ 头文件中。

但是从中生成的 IDL 描述和类型库有助于生成胶水代码,以便使用 C# 和其他语言的 COM 类。我记得它还可以帮助生成通过CoCreateInstance 和朋友使用您的 COM 类所需的 Windows 注册表项和值。所以它是一种基础结构机器,可以说,本质上支持独立于语言的视图和 COM 类的使用。

干杯,

【讨论】:

  • 我仍然看不到编译器和 COM 接口(在本例中为 ITopologyQuery)的用户如何知道必须创建 CTopologyQuery 的实例。 .idl 文件中的“library TopologyQueryLib{...}”块是必需的还是没用?
  • @Carl:没有魔法,即使在 COM 中也是如此。实例化 COM 对象的常用方法是调用 CoCreateInstance,给它一个类的 128 位 CLSID(它是一个 UUID),一个 128 位 IID(它是一个 UUID)类必须提供的接口。它在注册表中查找该 CLSID,从而为其提供服务器、DLL 或 EXE。然后它向该服务器请求一个实例。它向实例询问接口。我对 EXE 服务器的实例化如何工作有点模糊,这是你的情况。但是,对于 DLL,它是由 DLL(众所周知的函数)提供的简单对象工厂。干杯,
  • @Carl (continued) ... 换句话说,COM 接口的用户可以通过创建您在 IDL 中所说的实现接口的类的实例来获取该接口的提供者.许多类可以实现一个接口(例如,所有类都实现 IUknown)。这就是 IDL 中类定义的目的:它用于通知用户至少存在实现接口的类。
  • 好吧,这澄清了一些事情,谢谢。我会做一些测试来帮助我更好地理解事情是如何运作的。
猜你喜欢
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 2013-02-26
  • 2011-01-10
  • 2012-06-03
  • 1970-01-01
  • 2012-11-01
  • 2011-03-21
相关资源
最近更新 更多