• 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;
            }
            ...
    };
    
  • 相关阅读:
    IOS 网络浅析-(四 get&post)
    IOS 网络浅析-(三 NSURLConnection代理)
    IOS 网络浅析 (二 网络异步请求)
    IOS 网络浅析(一 网络监测~Reachability)
    IOS 杂笔- 6(KVC-KVO)
    IOS 杂笔-5(NSTimer极浅析)
    IOS 杂笔-4(属性与成员变量的区别)
    No address associated with hostname
    安卓中使用OkHttp发送数据请求的两种方式(同、异步的GET、POST) 示例-- Android基础
    Android中SharedPerforences的简单使用示例 --Android基础
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2674899.html
Copyright © 2020-2023  润新知