coclass

创建可实现 COM 接口的 COM 对象。

语法

[coclass]

备注

coclass C++ 特性将 coclass 构造放置在生成的 .idl 文件中。

定义 coclass 时,还可以指定 uuidversionthreadingvi_progidprogid 特性。 如果未指定其中任何一个,系统会生成它。

如果两个头文件包含具有 coclass 特性的类且未指定 GUID,则编译器将为这两个类使用相同的 GUID,这会导致 MIDL 错误。 因此,在使用 coclass 时,应使用 uuid 特性。

ATL 项目

当此特性位于 ATL 项目中的类或结构定义之前时,它会执行以下操作:

  • 注入代码或数据以支持对象的自动注册。

  • 注入代码或数据以支持对象的 COM 类工厂。

  • 注入代码或数据以实现 IUnknown,并使此对象成为可通过 COM 创建的对象。

具体而言,以下基类将添加到目标对象:

最后,未使用嵌入式 IDL 定义的任何双接口都会被替换为相应的 IDispatchImpl 类。 如果在嵌入式 IDL 中定义了双接口,则基列表中的特定接口不会进行修改。

coclass 特性还通过注入的代码提供以下函数,或在使用 GetObjectCLSID 的情况下,将以下函数作为基类 CComCoClass 中的静态方法提供:

  • UpdateRegistry 注册目标类的类工厂。

  • GetObjectCLSID 与注册相关,还可用于获取目标类的 CLSID。

  • GetObjectFriendlyName 默认返回格式为“<目标类名>Object”的字符串。 如果此函数已存在,则不会添加它。 将此函数添加到目标类,以返回比自动生成的名称更易记的名称。

  • 与注册相关的 GetProgID 返回使用 progid 特性指定的字符串。

  • GetVersionIndependentProgID 具有与 GetProgID 相同的功能,但返回使用 vi_progid 指定的字符串。

以下与 COM 映射相关的更改是针对目标类进行的:

类的 .idl 文件中生成的 coclass 的名称将与类的名称相同。 如果需要示例,尤其是需要参阅以下示例,以便在客户端中通过 MIDL 生成的头文件来访问 coclass CMyClass 的类 ID,请使用 CLSID_CMyClass

示例

以下代码显示了如何使用 coclass 特性:

// cpp_attr_ref_coclass1.cpp
// compile with: /LD
#include "unknwn.h"
[module(name="MyLib")];

[ object, uuid("00000000-0000-0000-0000-000000000001") ]
__interface I {
   HRESULT func();
};

[coclass, progid("MyCoClass.coclass.1"), vi_progid("MyCoClass.coclass"),
appobject, uuid("9E66A294-4365-11D2-A997-00C04FA37DDB")]
class CMyClass : public I {};

以下示例演示如何重写由 coclass 特性注入的代码中显示的函数的默认实现。 有关查看插入的代码的详细信息,请参阅 /Fx 。 用于类的任何基类或接口将显示在注入的代码中。 此外,如果注入代码中默认包含类,而你显式指定该类作为 coclass 的基类,则属性提供程序将使用代码中指定的形式。

// cpp_attr_ref_coclass2.cpp
// compile with: /LD
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
#include <atlplus.h>

[module(name="MyLib")];

[object, uuid("00000000-0000-0000-0000-000000000000")]
__interface bb {};

[coclass, uuid("00000000-0000-0000-0000-000000000001")]
class CMyClass : public bb {
public:
   // by adding the definition of UpdateRegistry to your code, // the function will not be included in the injected code
   static HRESULT WINAPI UpdateRegistry(BOOL bRegister) {
      // you can add to the default implementation
      CRegistryVirtualMachine rvm;
      HRESULT hr;
      if (FAILED(hr = rvm.AddStandardReplacements()))
         return hr;
      rvm.AddReplacement(_T("FriendlyName"), GetObjectFriendlyName());
      return rvm.VMUpdateRegistry(GetOpCodes(), GetOpcodeStringVals(),       GetOpcodeDWORDVals(), GetOpcodeBinaryVals(), bRegister);
   }
};

要求

特性上下文
适用于 classstruct
可重复
必需的特性
无效的特性

有关特性上下文的详细信息,请参见 特性上下文

另请参阅

IDL 特性
COM 特性
类特性
Typedef、Enum、Union 和 Struct 特性
appobject