Flylib.com

Books Software

 
 
 

Essential COM - page 27

IUnknown

÷ DuplicatePointer DestroyPointer , AddRef Release IUnknown ÷ , , . , . AddRef/Release , , .

(Component Object Model Specification) ÷ ÷ . ø ÷ - C++. ÷ :

  1. ÷ , AddRef .
  2. ÷ , , Release , ÷ , ÷ ÷.
  3. ÷ ÷ AddRef Release , ÷ .

, ÷ (, ÷ ). , ÷ AddRef Release , . ÷ ÷, ø ÷, 8500 ÷ 14.4 /, ÷ ÷ .

ø ÷ , , ÷ , AddRef Release . ÷ , AddRef :

  • 1. .
  • 2. ø [out] [in, out] .
  • A3. ÷ (physical result) .
  • 4. ø .

÷ , Release :

  • R1. .
  • R2. .
  • R3. [in,out] , ÷ ÷ ÷ . , ÷ [out] .
  • R4. .
  • R5. ø , ÷ .

÷ , , ÷ [in] :

  • S1. ÷ [in] -, AddRef Release , , , .

, , .

× ÷ , , ÷ , :

{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
void GetObject([out] IUnknown **ppUnk);

÷ , :

void UseObject([in] IUnknown *pUnk);

, ÷ . , , :

void GetAndUse(/* [out] */ IUnknown ** ppUnkOut) 
{ 
    IUnknown *pUnk1 = 0, *pUnk2 = 0; 
    *ppUnkOut =0;                                      // R3 

      // get pointers to one (or two) objects 
      // получаем указатели на один (или два) объекта 

    GetObject(&pUnk1);                               //A2 
    GetObject(&pUnk2);                               //A1
 
      // set pUnk2 to point to first object 
      // устанавливаем pUnk2, чтобы указать на первый объект 

    if (pUnk2) pUnk2->Release():                          //R1
    if (pUnk2 = pUnk1) pUnk2->AddRef():                   //A1

      // pass pUnk2 to some other function 
      // передаем pUnk2 какой-нибудь другой функции 
  
    UseObject(pUnk2);                                   //S1

      // return pUnk2 to caller using ppUnkOut parameter 
      // возвращаем pUnk2 вызывающему объекту, используя 
      // параметр ppUnkOut 

    if (*ppUnkOut = pUnk2) (*ppUnkOut)->AddRef();     // A2 

      // falling out of scope so clean up 
      // выходит за область действия и поэтому освобождаем 

    if (pUnk1) pUnkl->Release();                         //R2 
    if (pUnk2) pUnk2->Release();                         //R2 
}

, ÷ ø A2 , ÷. GetObject , GetObject . ÷, ÷ GetObject AddRef ÷ [out] . , ppUnkOut , AddRef ÷ .

AddRef Release , . AddRef , Release ÷ 32- ÷ . ÷ ÷ ø AddRef Release . ÷, ÷ , , , ÷ ÷ ÷ ÷ , , .

÷, , Release . Release , ÷ . . ÷, ÷ Release , , ÷ . ÷, Release , AddRef , ÷ . , ÷ - ÷, , , , . × (released) , , , Release :

inline void SafeRelease(IUnknown * &rpUnk) 
{ 
    if (rpUnk) { 
        rpUnk->Release(); 
        rpUnk = 0; 
      // rpUnk passed by reference 
      // rpUnk, переданный ссылкой 
    } 
}

, ø . ø , , .

, AddRef Release , . GetAndUse , , ÷ . ÷, ÷ , , ø . ø , - return , ÷ , (unhandled) ÷ C++, - ø , , ÷ . ÷, ÷ , , ÷ C++. ÷, , , ÷ . -, ÷ Release .

IUnknown

, ÷ ÷ . ß C++ ÷ dynamic_cast . , - , ÷ dynamic_cast . IDL- QueryInterface :

HRESULT QueryInterface([in] REFIID riid, [out] void **ppv);

( riid ) ÷ ø . (ppv) , ÷ ø ø ø .

QueryInterface , ø , E_NOINTERFACE *ppv ÷. ø , *ppv ø HRESULT S_OK . ppv [out] -, QueryInterface AddRef , (. ø 2). AddRef Release . ÷ C++ dynamic_cast Dog/Cat , :

void TryToSnoreAndIgnore(/* [in] */ IUnknown *pUnk) 
{ 
    IPug *pPug = 0;
    pPug = dynamic_cast<IPug*> (pUnk); 
    if (pPug) 
        // the object is Pug-compatible 
        // объект совместим с Pug 
        pPug->Snore(); 
    ICat *pCat = 0; 
    pCat = dynamic_cast<ICat*>(pUnk); 
    if (pCat) 
        // the object is Cat-compatible 
        // объект совместим с Cat pCat->
        IgnoreMaster(); 
}

, , ICat IDog , . ICat IDog , ( ). ÷ QueryInterface :

void TryToSnoreAndIgnore(/* [in] */ IUnknown *pUnk) 
{ 
    HRESULT hr; 
    IPug *pPug = 0; 
    hr = pUnk->QueryInterface(IID_IPug, (void**)&pPug); 
    if (SUCCEEDED(hr)) { 
          // the object is Pug-compatible 
          // объект совместим с Pug 
        pPug->Snore(); 
        pPug->Release(); // R2 
    } 

    ICat *pCat = 0; 
    hr = pUnk->QueryInterface(IID_ICat, (void**)&pCat); 
    if (SUCCEEDED(hr)) { 
          // the object is Cat-compatible 
          // объект совместим с Cat
        pCat->IgnoreMaster(); 
        pCat->Release(); // R2 
    } 
}

÷ ÷ , , ÷ , QueryInterface , ÷ ÷ .

, QueryInterface . QueryInterface -, . 4 . , , ÷, ÷ AddRef Release . . ÷, ÷ ø÷:

void BadCOMCode(/*[in]*/ IUnknown *pUnk) 
{ 
    ICat *pCat = 0; 
    IPug *pPug = 0; 
    HRESULT hr;
    hr = pUnk->QueryInterface(IID_ICat, (void**)&pCat); 
    if (FAILED(hr)) goto cleanup; 
    hr = pUnk->QueryInterface(IID_IPug, (void**)&pPug); 
    if (FAILED(hr)) goto cleanup; 
    pPug->Bark(); 
    pCat->IgnoreMaster(); 
  cleanup: 
    if (pCat) pUnk->Release(); 
      // pCat got AddRefed in QI 
      // pCat получил AddRef в QI 
    if (pPug) pUnk->Release(); 
      // pDog got AddRefed in QI 
      // pDog получил AddRef в QI 
}

÷ : pCat , pPug pUnk - , AddRef , pCat pPug QueryInterface , Release pUnk . :

cleanup: 
    if (pCat) pCat->Release(); 
      // use AddRefed ptr 
      // используем указатель AddRef 
    if (pPug) pPug->Release(); 
      // use AddRefed ptr 
      // используем указатель AddRef

Release , AddRef (÷ ø , QueryInterface ). ÷ ÷ . , ø ÷ , ÷ , ÷ .

QueryInterface , void** . , ÷ QueryInterface , , C++:

HRESULT _stdcall QueryInterface(REFIID riid, void** ppv);

÷ , QueryInterface , ÷ IID , :

{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
IPug *pPug = 0; 
hr = punk->QueryInterface(IID_IPug, (void**)&pPug);

, C++ :

IPug *pPug = 0; 
hr = punk->QueryInterface(IID_ICat, (void**)&pPug);

ø:

IPug *pPug = 0; 
hr = punk->QueryInterface(IID_IPug, (void**)pPug);

, ÷ , QueryInterface e ÷ :

HRESULT QueryInterface(REFIID riid, IUnknown** ppv);

( upcasting ) , :

IDerived **ppd; 
IBase **ppb = ppd; 
// illegal 
// неверно

To ÷ . :

HRESULT QueryInterface(const IID& riid, void* ppv);

(cast). , ø ø ÷ ø ( ø ø ), , ÷ , ÷ ÷ C++ . QueryInterface , , Microsoft, , , . ø ø, c QueryInterface , - , ÷ IID , QueryInterface . QueryInterface "" . :

#define IID_PPV_ARG(Type, Expr) IID_##type, \ 
reinterpret_cast<void**>(static_cast<Type **>(Expr))

1 , ÷ , QueryInterface , ÷ (indirecton):

IPug *pPug = 0; 
hr = punk->QueryInterface(IID_PPV_ARG(IPug, &pPug));

ø, void** , - .


1 ÷ Tye McQueen .