ATL 对象映射表

本文深入解析了C++中使用ATL库实现COM对象映射的原理、方法及关键结构,包括如何通过OBJECT_ENTRY_AUTO宏定义COM可创建类,并在内存中连续存储对象描述信息,以便进行注册、实例化等操作。
摘要由CSDN通过智能技术生成

 

一.作用

Each coclass adds an entry to the object map by allocating the _ATL_OBJMAP_ENTRY structure (discussed in detail shortly) within that same data segment. This produces a series of _ATL_OBJMAP_ENTRY structures that are contiguous in memory and, thus, can easily be iterated over by CAtlModule when it needs to perform registration, class object creation, and other class-management services.

二.添加方法

Each class inserts an item into the object map via the OBJECT_ENTRY_AUTO macro declared in the class header file outside the class declaration itself, as in the following:

class CMyClass : public CComCoClass< ... >, ...
{
public:


   ...
};

OBJECT_ENTRY_AUTO(__uuidof(MyClass), CMyClass)

三._ATL_OBJMAP_ENTRY Structure

 
struct _ATL_OBJMAP_ENTRY30
{
    const CLSID* pclsid;
    HRESULT (WINAPI *pfnUpdateRegistry)(_In_ BOOL bRegister);
    _ATL_CREATORFUNC* pfnGetClassObject;
    _ATL_CREATORFUNC* pfnCreateInstance;
    IUnknown* pCF;
    DWORD dwRegister;
    _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
    _ATL_CATMAPFUNC* pfnGetCategoryMap;
    HRESULT WINAPI RevokeClassObject()
    {
        if (dwRegister == 0)
            return S_OK;
        return CoRevokeClassObject(dwRegister);
    }
    HRESULT WINAPI RegisterClassObject(
        _In_ DWORD dwClsContext,
        _In_ DWORD dwFlags)
    {
        IUnknown* p = NULL;
        if (pfnGetClassObject == NULL)
            return S_OK;
        HRESULT hRes = pfnGetClassObject(pfnCreateInstance, __uuidof(IUnknown), (LPVOID*) &p);
        if (SUCCEEDED(hRes))
            hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
        if (p != NULL)
            p->Release();
        return hRes;
    }
// Added in ATL 3.0
    void (WINAPI *pfnObjectMain)(_In_ bool bStarting);
};

typedef _ATL_OBJMAP_ENTRY30 _ATL_OBJMAP_ENTRY;
 
介绍

四.OBJECT_ENTRY_AUTO Macro

You use the OBJECT_ENTRY_AUTO macro to specify a COM-createable class. Typically, this means the specified class derives from the CComCoClass base class. Often these are top-level objects in an object model. Clients typically create such top-level objects using CoCreateInstance.

#define OBJECT_ENTRY_AUTO(clsid, class) \
    __declspec(selectany) ATL::_ATL_OBJMAP_ENTRY __objMap_##class = {&clsid, class::UpdateRegistry, class::_ClassFactoryCreatorClass::CreateInstance, class::_CreatorClass::CreateInstance, NULL, 0, class::GetObjectDescription, class::GetCategoryMap, class::ObjectMain }; \
    extern "C" __declspec(allocate("ATL$__m")) __declspec(selectany) ATL::_ATL_OBJMAP_ENTRY* const __pobjMap_##class = &__objMap_##class; \
    OBJECT_ENTRY_PRAGMA(class)

知识背景

__declspec(selectany)的作用

c++ 中__declspec 的用法

理解这个宏是重点

#pragma section("ATL$__a", read)
#pragma section("ATL$__z", read)
#pragma section("ATL$__m", read)
extern "C"
{
__declspec(selectany) __declspec(allocate("ATL$__a")) _ATL_OBJMAP_ENTRY* __pobjMapEntryFirst = NULL;
__declspec(selectany) __declspec(allocate("ATL$__z")) _ATL_OBJMAP_ENTRY* __pobjMapEntryLast = NULL;
}

The alphabetical order of sections in the resulting file is guaranteed through a special naming rule enforced by the linker

#define OBJECT_ENTRY(clsid, class) {&clsid, class::UpdateRegistry, class::_ClassFactoryCreatorClass::CreateInstance, class::_CreatorClass::CreateInstance, NULL, 0, class::GetObjectDescription, class::GetCategoryMap, class::ObjectMain },

如上面代码将会生成如下对象映射表

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值