一个COM例子

来源:互联网 发布:美国红脖子 知乎 编辑:程序博客网 时间:2024/05/19 03:43


来自:http://hi.baidu.com/starloooooove/item/df8a17ad8f7893aa29ce9dc5


学习DX一堆接口之前的知识补充,小的不能再小了。

一个COM对象实际上就是实现大量界面的C++类或者是一套C++类, 一个界面就是一套函数。

如图:一个COM对象,有IGRAPHICS、ISOUND和IINPUT三个界面。

<span style="font-size:14px;">每一个界面都有大量的函数可以调用,COM技术要求用户创建的所有的界面必须从一个指定的基本类界面IUnknown中导出,以具备功能:引用计数和查询接口。</span><span style="font-size:14px;">interface   IUnknown  {            virtual   HRESULT   _stdcall   QueryInterface(const IID   & iid,   (void**) ip)=0;            virtual   ULONG   _stdcall   AddRef(void)=0;            virtual   ULONG   _stdcall   Release(void)=0;  }   IUnknown是所有接口的基础,他负责两项工作:             IUnknown::QueryInterface负责得到该组件的其他接口的指针。         IUnknown::AddRef/Release负责管理该组件的生存期,但有人使用该组件时,保证该组件不会被意外删除;再没人使用该组件时,保证该组件被自动删除。例子:1、定义IX、IY两个接口// define the IX interfaceinterface IX: IUnknown{virtual void __stdcall fx(void)=0;};// define the IY interfaceinterface IY: IUnknown{virtual void __stdcall fy(void)=0;};2、定义COM对象class CCOM_OBJECT : public IX,                    public IY{public:CCOM_OBJECT() : ref_count(0) {}~CCOM_OBJECT() {}private:virtual HRESULT __stdcall QueryInterface(const IID &iid, void **iface);virtual ULONG __stdcall AddRef();virtual ULONG __stdcall Release();virtual void __stdcall fx(void) {cout << "Function fx has been called." << endl; }virtual void __stdcall fy(void) {cout << "Function fy has been called." << endl; }int ref_count;};3、具体实现QueryInterface、AddRef和ReleaseHRESULT __stdcall CCOM_OBJECT::QueryInterface(const IID &iid, void **iface){// requesting the IUnknown base interfaceif (iid==IID_IUnknown){cout << "Requesting IUnknown interface" << endl;*iface = (IX*)this;} // end if// maybe IX?if (iid==IID_IX){cout << "Requesting IX interface" << endl;*iface = (IX*)this;} // end ifelse // maybe IYif (iid==IID_IY){cout << "Requesting IY interface" << endl;*iface = (IY*)this;} // end ifelse{ // cant find it!cout << "Requesting unknown interaface!" << endl;*iface = NULL;return(E_NOINTERFACE);} // end else// if everything went well cast pointer to IUnknown and call addref()((IUnknown *)(*iface))->AddRef();return(S_OK);} // end QueryInterface////////////////////////////////////////////////////////////////////////////////////////////////ULONG __stdcall CCOM_OBJECT::AddRef(){// increments reference countcout << "Adding a reference" << endl;return(++ref_count);} // end AddRef///////////////////////////////////////////////////////////////////////////////////////////////ULONG __stdcall CCOM_OBJECT::Release(){// decrements reference countcout << "Deleting a reference" << endl;if (--ref_count==0){delete this;return(0);} // end ifelsereturn(ref_count);} // end Release4、创建实例IUnknown *CoCreateInstance(void){IUnknown *comm_obj = (IX *)new(CCOM_OBJECT);cout << "Creating Comm object" << endl;comm_obj->AddRef();return(comm_obj);}5、Main调用// create the main COM objectIUnknown *punknown = CoCreateInstance() ;// create two NULL pointers the the IX and IY interfacesIX *pix=NULL;IY *piy=NULL;// from the original COM object query for interface IXpunknown->QueryInterface(IID_IX, (void **)&pix);// try some of the methods of IXpix->fx();// release the interfacepix->Release();// now query for the IY interfacepunknown->QueryInterface(IID_IY, (void **)&piy);// try some of the methodspiy->fy();// release the interfacepiy->Release();// release the COM object itselfpunknown->Release();</span>


0 0
原创粉丝点击