天天看点

COM学习笔记三四《COM技术内幕》--接口和QueryInterface函数

实现 了 §2 和 §3 的 简单 的程序, 这 些程序并不是完全意 义 上的 COM 程序。 §2 —— IFACE.CPP 代 码 清 单 :

// //Iface.cpp // // #include <iostream.h> #include <objbase.h>      //Define interface void trace( const char * pMsg) {cout << pMsg << endl ;} interface IX {           virtual void __stdcall Fx1() = 0;           virtual void __stdcall Fx2() = 0; }; interface IY {           virtual void __stdcall Fy1() = 0;           virtual void __stdcall Fy2() = 0; }; class CA : public IX, public IY { public :           virtual void __stdcall Fx1() {cout << "CA::Fx1" << endl ;}           virtual void __stdcall Fx2() {cout << "CA::Fx2" << endl ;}           virtual void __stdcall Fy1() {cout << "CA::Fy1" << endl ;}           virtual void __stdcall Fy2() {cout << "CA::Fy2" << endl ;} }; int main() {          trace( "Client:Create an instance of the component." );          CA* pA = new CA;          IX* pIX = pA;          trace( "Client:Use the IX interface." );          pIX->Fx1();          pIX->Fx2();          IY* pIY = pA;          trace( "Client:Use the IY interface." );          pIY->Fy1();          pIY->Fy2();          trace( "Client:Delete the component." );           delete pA;           return 0; }   §3 —— IUnknown.CPP 代 码 清 单 : // //IUnkown.cpp // // #include <iostream.h> #include <objbase.h> void trace(const char * msg) {cout << msg << endl ;} //Interface interface IX : IUnknown {           virtual void __stdcall Fx() = 0; }; interface IY : IUnknown {           virtual void __stdcall Fy() = 0; }; interface IZ : IUnknown {           virtual void __stdcall Fz() = 0; }; //Forward references for GUIDs extern const IID IID_IX; extern const IID IID_IY; extern const IID IID_IZ; // //Component // class CA : public IX, public IY {           //IUnknown implementation           virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);           virtual ULONG   __stdcall AddRef() {return 0;}           virtual ULONG   __stdcall Release() {return 0;}           //Interface IX implementation           virtual void        __stdcall Fx() {cout << "Fx" << endl ;}           //Interface IY implementation           virtual void        __stdcall Fy() {cout << "Fy" << endl ;} }; HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv) {           if(iid == IID_IUnknown)           {                     trace("QueryInterface:Return pointer to IUnknown.");                     *ppv = static_cast< IX* >(this);           }           else if(iid == IID_IX)           {                     trace("QueryInterface:Return pointer to IX.");                     *ppv = static_cast< IX* >(this);           }           else if(iid == IID_IY)           {                     trace("QueryInterface:Return pointer to IY.");                     *ppv = static_cast< IY* >(this);           }           else           {                     trace("QueryInterface:Interface not supported.");                     *ppv = NULL;                     return E_NOINTERFACE;           }           reinterpret_cast< IUnknown* >(*ppv)->AddRef();           return S_OK; } // //Creation function // IUnknown* CreateInstance() {           IUnknown* pI = static_cast< IX* >(new CA);           pI->AddRef();           return pI; } // //IIDs // //{32bb8320-b41b-11cf-a6bb-0080c7b2d682} static const IID IID_IX =           {0x32bb8320, 0xb41b, 0x11cf,           {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; //{32bb8321-b41b-11cf-a6bb-0080c7b2d682} static const IID IID_IY =           {0x32bb8321, 0xb41b, 0x11cf,           {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; //{32bb8322-b41b-11cf-a6bb-0080c7b2d682} static const IID IID_IZ =           {0x32bb8322, 0xb41b, 0x11cf,           {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; // //Client // int main() {           HRESULT hr;           trace("Client:Get an IUnknown pointer.");           IUnknown* pIUnknown = CreateInstance();           trace("Client:Get Interface IX.");           IX* pIX = NULL;           hr = pIUnknown->QueryInterface(IID_IX,(void**)&pIX);           if(SUCCEEDED(hr))           {                     trace("Client:Succeeded getting IX.");                     pIX->Fx();        //Use interface IX           }                     trace("Client:Get Interface IY.");           IY* pIY = NULL;           hr = pIUnknown->QueryInterface(IID_IY,(void**)&pIY);           if(SUCCEEDED(hr))           {                     trace("Client:Succeeded getting IY.");                     pIY->Fy();        //Use interface IY           }                               trace("Client:Get Interface IZ.");           IZ* pIZ = NULL;           hr = pIUnknown->QueryInterface(IID_IZ,(void**)&pIZ);           if(SUCCEEDED(hr))           {                     trace("Client:Succeeded getting IZ.");                     pIZ->Fz();           }           else           {                     trace("Client:Could not get interface IZ.");           }           trace("Client:Get interface IY from interface IX.");           IY* pIYfromIX = NULL;           hr = pIX->QueryInterface(IID_IY, (void**)&pIYfromIX);           if(SUCCEEDED(hr))           {                     trace("Client:Succeeded getting IY.");                     pIYfromIX->Fy();           }           trace("Client:Get interface IUnknown from IY.");           IUnknown* pIUknownFromIY = NULL;           hr = pIY->QueryInterface(IID_IUnknown, (void**)&pIUknownFromIY);           if(SUCCEEDED(hr))           {                     cout << "equal?" ;                     if(pIUknownFromIY == pIUnknown)                     {                              cout << "Yes." << endl;                     }                     else                     {                              cout << "No." << endl;                     }           }           //Delete the component           delete pIUnknown;           return 0; }