• ATL 核心COM继承类之CComObjectRootEx及CComObjectLock


    参考:

    1. ATL 临界区

    2. ATL 引用计数线程模型

    • CComObjectRootEx Manages reference counting for both aggregated and nonaggregated objects. Allows you to specify a threading model.

    • CComObjectRoot Manages reference counting for both aggregated and nonaggregated objects. Uses the default threading model of the server.

    记住这句话就可以了:Manages reference counting.

    template <class ThreadModel>
    class CComObjectRootEx : 
        public CComObjectRootBase
    {
    public:
        typedef ThreadModel _ThreadModel;
        typedef typename _ThreadModel::AutoCriticalSection _CritSec;
        typedef typename _ThreadModel::AutoDeleteCriticalSection _AutoDelCritSec;
        typedef CComObjectLockT<_ThreadModel> ObjectLock;
    
        ~CComObjectRootEx() 
        {
        }
    
        ULONG InternalAddRef()
        {
            ATLASSUME(m_dwRef != -1L);
            return _ThreadModel::Increment(&m_dwRef);
        }
        ULONG InternalRelease()
        {
    #ifdef _DEBUG
            LONG nRef = _ThreadModel::Decrement(&m_dwRef);
            if (nRef < -(LONG_MAX / 2))
            {
                ATLASSERT(0 && _T("Release called on a pointer that has already been released"));
            }
            return nRef;
    #else
            return _ThreadModel::Decrement(&m_dwRef);
    #endif
        }
    
        HRESULT _AtlInitialConstruct()
        {
            return m_critsec.Init();
        }
        void Lock() 
        {
            m_critsec.Lock();
        }
        void Unlock() 
        {
            m_critsec.Unlock();
        }
    private:
        _AutoDelCritSec m_critsec;
    };
    
    template <>
    class CComObjectRootEx<CComSingleThreadModel> : 
        public CComObjectRootBase
    {
    public:
        typedef CComSingleThreadModel _ThreadModel;
        typedef _ThreadModel::AutoCriticalSection _CritSec;
        typedef _ThreadModel::AutoDeleteCriticalSection _AutoDelCritSec;
        typedef CComObjectLockT<_ThreadModel> ObjectLock;
    
        ~CComObjectRootEx() {}
    
        ULONG InternalAddRef()
        {
            ATLASSUME(m_dwRef != -1L);
            return _ThreadModel::Increment(&m_dwRef);
        }
        ULONG InternalRelease()
        {
    #ifdef _DEBUG
            long nRef = _ThreadModel::Decrement(&m_dwRef);
            if (nRef < -(LONG_MAX / 2))
            {
                ATLASSERT(0 && _T("Release called on a pointer that has already been released"));
            }
            return nRef;
    #else
            return _ThreadModel::Decrement(&m_dwRef);
    #endif    
        }
    
        HRESULT _AtlInitialConstruct()
        {
            return S_OK;
        }
    
        void Lock() 
        {
        }
        void Unlock() 
        {
        }
    };
    
    typedef CComObjectRootEx<CComObjectThreadModel> CComObjectRoot;
    

    CComObjectLockT

    为ComObject锁方法提供便利

    template <class ThreadModel>
    class CComObjectRootEx;
    
    template <class ThreadModel>
    class CComObjectLockT
    {
    public:
        CComObjectLockT(_Inout_opt_ CComObjectRootEx<ThreadModel>* p)
        {
            if (p)
                p->Lock();
            m_p = p;
        }
    
        ~CComObjectLockT()
        {
            if (m_p)
                m_p->Unlock();
        }
        CComObjectRootEx<ThreadModel>* m_p;
    };
    

    前后对比

    class CPenguin
        : public CComObjectRootEx<CComMultiThreadModel>, ... {
            STDMETHODIMP get_Wingspan(long* pnWingspan) {
                Lock();
                if( !pnWingspan ) return E_POINTER; // Forgot to Unlock
                *pnWingSpan = m_nWingspan;
                Unlock();
                return S_OK;
            }
            ...
    };
    
    class CPenguin
        : public CComObjectRootEx<CComMultiThreadModel>, ... {
            STDMETHODIMP get_Wingspan(long* pnWingspan) {
                ObjectLock lock(this);
                if( !pnWingspan ) return E_POINTER; // Unlock happens as
                // stack unwinds
                *pnWingSpan = m_nWingspan;
                return S_OK;
            }
            ...
    };
    
  • 相关阅读:
    HIVE Group by、join、distinct等实现原理
    【1.3】shell基础——调试shell(sh -x)
    sql server无法显示请求的对话框,检索数据失败
    sql server索引操作
    sql server中的alter
    tempdb无法收缩。使用 DBCC FREESYSTEMCACHE 解决
    在从该备份集进行读取时,RESTORE 检测到在数据库 "CISDB" 中的页(0:0)上存在错误。系统断定检查已失败
    【1.2】shell基础——stty erase解决按backspace出现^H的情况
    【1.1】shell基本实践——密码输入三次错误则结束
    (5.3.7)数据库迁移——sql server备份文件的加密解密
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2674899.html
Copyright © 2020-2023  润新知