代码改变世界

ATL 对象映射表

  Clingingboy  阅读(1224)  评论(0编辑  收藏  举报

 

一.作用

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;
 
介绍
image

四.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

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示