Flylib.com

Books Software

 
 
 

Essential COM - page 51

?

-. - , , . . CoGetClassObject , . CoCreateInstanceEx , a CoGetInstanceFromFile , . ÷ ÷ , ÷ MkParseDisplayName ÷ .

4.

class object {
  public:
    template <class T> virtual 
    T * dynamic_cast(const type_info& t = typeid(T) )
};

Аноним, 1995

2 IUnknown ÷. , ÷ . , ø , ÷ . - QueryInterface ( ) - ++- dynamic_cast, .

, ÷ QueryInterface , ÷ , ÷ ÷ this , ø . ÷ ÷ , , C++ dynamic_cast .

QueryInterface , IUnknown ÷ ÷ ø , ÷ . , , .

Unknown
QueryInterface ÷
QueryInterface
QueryInterface
÷

QueryInterface IUnknown

÷
÷
÷
?

IUnknown

IUnknown ÷, ÷ . ÷ SDK , ø , QueryInterface , AddRef Release , C++. ( Component Object Model Specification ) ÷ ÷ , . IUnknown ÷ IUnknown , ÷ .

2 ÷ ++- , . , ÷ , - ÷ IUnknown . , ø ø . ø ÷ , , ÷ , , , ÷ , - vptr . , , IUnknown vptr , .

IUnknown , ÷ ÷ . × IUnknown, ÷ . :

import "unknwn.idl";
[object, uuid(CD538340-A56D-11d0-8C2F-0080C73925BA)] 
interface IVehicle : IUnknown {
    HRESULT GetMaxSpeed([out, retval] long *pMax);
}

[object, uuid(CD53834l-A56D-11d0-8C2F-0080C73925BA)] 
interface ICar : IVehicle {
    HRESULT Brake(void);
}

[object, uuid(CD538342-A56D-11d0-8C2F-0080C73925BA)] 
interface IPlane : IVehicle {
    HRESULT TakeOff(void);
}

[object, uuid(CD538343-A56D-11d0-8C2F-0080C73925BA)]
interface IBoat : IVehicle {
    HRESULT Sink(void);
}

. , . IUnknown . 4.1 CarBoatPlane , ÷ . , ÷ , , : ÷ , CarBoatPlane : IBoat , IPlane , ICar , IVehicle IUnknown .

IUnknown , , - , ÷ QueryInterface ÷, ( Symmetric/Transitive/Reflexive ). ø ÷ ( identity ) . IUnknown , , ÷ ÷ , , ÷ ÷ .

. 4.1. carboatplane

QueryInterface ÷

, ÷, QueryInterface B ÷ A , QueryInterface A ÷ ø. ÷, ÷

QI(A)->B
QI(QI(A)->B)->A

. 4.2. queryinterface

, . 4.2, , ÷ , ÷ , :

void AssertSymmetric(ICar *pCar) 
{
    if (pCar) { 
        IPlane *pPlane = 0;
          // request a second type of interface 
          // запрашиваем второй тип интерфейса 
        HRESULT hr = pCar->QueryInterface(IID_IPlane, (void**)&pPlane);
        if (SUCCEEDED(hr)) {
            ICar *pCar2 = 0;
              // request original type of interface 
              // запрашиваем исходный тип интерфейса 
            hr = pPlane->QueryInterface(IID_ICar, (void**)&pCar2);
              // if the following assertion fails, pCar
              // did not point to a valid СОМ object
              // если следующее утверждение не будет правильным,
              // то pCar не укажет на правильный СОМ-объект
            assert(SUCCEEDED(hr));
            pCar2->Release();
        } 
        pPlane->Release();
    } 
}

÷ QueryInterface ÷ , ÷ , ø , ø .

QueryInterface

, ÷, QueryInterface ÷ A , QueryInterface C ÷ , QueryInterface C ÷ A ø. ÷, ÷

QI(QI(A)->B)->C
QI(A)->C

. 4.3 ÷, ÷ , , :

void AssertTransitive(ICar *pCar)
{
    if (pCar) { 
        IPlane *pPlane = 0;
          // request intermediate type of interface 
          // запрос промежуточного типа интерфейса 
        HRESULT hr = pCar->QueryInterface(IID_IPlane, (void**)&pPlane);
        if (SUCCEEDED(hr)) {
            IBoat *pBoat1 = 0;
              // request terminal type of interface 
              // запрос конечного типа интерфейса 
            hr = pPlane->QueryInterface(IID_IBoat, (void**)&pBoat1);
            if (SUCCEEDED(hr)) {
                IBoat *pBoat2 = 0;
                  // request terminal type through the original pointer 
                  // запрос конечного типа через исходный указатель
                hr = pCar->QueryInterface(IID_IBoat, (void**)&pBoat2);
                  // if the following assertion fails, pCar
                  // did not point to a valid СОМ object
                  // если следующее утверждение неверно, то pCar
                  // не указывал на корректный СОМ-объект
                assert(SUCCEEDED(hr));
                pBoat2->Release();
            }
            pBoat1->Release();
        } 
        pPlane->Release();
    } 
}

. 4.3. queryinterface

QueryInterface , ÷ , , , ÷ - . , ø , ÷ QueryInterface . ÷ QueryInterface , ÷ "/" QueryInterface . , ÷, . , ÷ QueryInterface .