combase.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 239 行

SVN-BASE
239
字号
//------------------------------------------------------------------------------// File: ComBase.cpp//// Desc: DirectShow base classes - implements class hierarchy for creating//       COM objects.//// Copyright (c) 1992-2002 Microsoft Corporation.  All rights reserved.//------------------------------------------------------------------------------#include "stdafx.h"#pragma warning( disable : 4514 )   // Disable warnings re unused inline functions/* Define the static member variable */LONG CBaseObject::m_cObjects = 0;/* Constructor */CBaseObject::CBaseObject(const TCHAR *pName){    /* Increment the number of active objects */    InterlockedIncrement(&m_cObjects);#ifdef DEBUG#ifdef UNICODE    m_dwCookie = DbgRegisterObjectCreation(0, pName);#else    m_dwCookie = DbgRegisterObjectCreation(pName, 0);#endif#endif}#ifdef UNICODECBaseObject::CBaseObject(const char *pName){    /* Increment the number of active objects */    InterlockedIncrement(&m_cObjects);#ifdef DEBUG    m_dwCookie = DbgRegisterObjectCreation(pName, 0);#endif}#endifHINSTANCE	hlibOLEAut32;/* Destructor */CBaseObject::~CBaseObject(){    /* Decrement the number of objects active */    if (InterlockedDecrement(&m_cObjects) == 0) {	if (hlibOLEAut32) {	    FreeLibrary(hlibOLEAut32);	    hlibOLEAut32 = 0;	}    };#ifdef DEBUG    DbgRegisterObjectDestruction(m_dwCookie);#endif}static const TCHAR szOle32Aut[]   = TEXT("OleAut32.dll");HINSTANCE LoadOLEAut32(){    if (hlibOLEAut32 == 0) {	hlibOLEAut32 = LoadLibrary(szOle32Aut);    }    return hlibOLEAut32;}/* Constructor */// We know we use "this" in the initialization list, we also know we don't modify *phr.#pragma warning( disable : 4355 4100 )CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk): CBaseObject(pName)/* Start the object with a reference count of zero - when the      *//* object is queried for it's first interface this may be          *//* incremented depending on whether or not this object is          *//* currently being aggregated upon                                 */, m_cRef(0)/* Set our pointer to our IUnknown interface.                      *//* If we have an outer, use its, otherwise use ours.               *//* This pointer effectivly points to the owner of                  *//* this object and can be accessed by the GetOwner() method.       */, m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) ) /* Why the double cast?  Well, the inner cast is a type-safe cast */ /* to pointer to a type from which we inherit.  The second is     */ /* type-unsafe but works because INonDelegatingUnknown "behaves   */ /* like" IUnknown. (Only the names on the methods change.)        */{    // Everything we need to do has been done in the initializer list}// This does the same as above except it has a useless HRESULT argument// use the previous constructor, this is just left for compatibility...CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :    CBaseObject(pName),    m_cRef(0),    m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) ){}#ifdef UNICODECUnknown::CUnknown(const CHAR *pName, LPUNKNOWN pUnk): CBaseObject(pName), m_cRef(0),    m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) ){ }CUnknown::CUnknown(const CHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :    CBaseObject(pName), m_cRef(0),    m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) ){ }#endif#pragma warning( default : 4355 4100 )/* QueryInterface */STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv){    CheckPointer(ppv,E_POINTER);    ValidateReadWritePtr(ppv,sizeof(PVOID));    /* We know only about IUnknown */    if (riid == IID_IUnknown) {        GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);        return NOERROR;    } else {        *ppv = NULL;        return E_NOINTERFACE;    }}/* We have to ensure that we DON'T use a max macro, since these will typically   *//* lead to one of the parameters being evaluated twice.  Since we are worried    *//* about concurrency, we can't afford to access the m_cRef twice since we can't  *//* afford to run the risk that its value having changed between accesses.        *//* AddRef */STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef(){    LONG lRef = InterlockedIncrement((LONG*) &m_cRef );    ASSERT(lRef > 0);    DbgLog((LOG_MEMORY,3,TEXT("    Obj %d ref++ = %d"),           m_dwCookie, m_cRef));    return std::max(ULONG(m_cRef), 1ul);}/* Release */STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease(){    /* If the reference count drops to zero delete ourselves */    LONG lRef = InterlockedDecrement( (LONG*)&m_cRef );    ASSERT(lRef >= 0);    DbgLog((LOG_MEMORY,3,TEXT("    Object %d ref-- = %d"),	    m_dwCookie, m_cRef));    if (lRef == 0) {        // COM rules say we must protect against re-entrancy.        // If we are an aggregator and we hold our own interfaces        // on the aggregatee, the QI for these interfaces will        // addref ourselves. So after doing the QI we must release        // a ref count on ourselves. Then, before releasing the        // private interface, we must addref ourselves. When we do        // this from the destructor here it will result in the ref        // count going to 1 and then back to 0 causing us to        // re-enter the destructor. Hence we add an extra refcount here        // once we know we will delete the object.        // for an example aggregator see filgraph\distrib.cpp.        m_cRef++;        delete this;        return ULONG(0);    } else {        return std::max(ULONG(m_cRef), 1ul);    }}/* Compares two interfaces and returns TRUE if they are on the same object */BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond){    /*  Different objects can't have the same interface pointer for        any interface    */    if (pFirst == pSecond) {        return TRUE;    }    /*  OK - do it the hard way - check if they have the same        IUnknown pointers - a single object can only have one of these    */    LPUNKNOWN pUnknown1;     // Retrieve the IUnknown interface    LPUNKNOWN pUnknown2;     // Retrieve the other IUnknown interface    HRESULT hr;              // General OLE return code    ASSERT(pFirst);    ASSERT(pSecond);    /* See if the IUnknown pointers match */    hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1);    ASSERT(SUCCEEDED(hr));    ASSERT(pUnknown1);    hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2);    ASSERT(SUCCEEDED(hr));    ASSERT(pUnknown2);    /* Release the extra interfaces we hold */    pUnknown1->Release();    pUnknown2->Release();    return (pUnknown1 == pUnknown2);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?