在很久以前,就因为项目的需求,接触到了组件的概念,但是由于各种原因(主要还是自己太懒...)没有系统的学习和理解组件.进几天项目空闲下来,我魔兽世界也85了..所以安心的把组件的知识梳理一遍,当然只是很基础很基础的东西,里面还参杂了一些自己的理解,写下来,可以让自己以后复习,也希望高手能指点,我的主要参考资料是《com技术内幕》,csdn上有下载。
什么是com组件?什么是com技术?这些有许多解释,我个人的理解就是控件咯,类咯,dll咯,总之就是个黑盒子,我不知道它是用啥实现的,只要给我接口,知道咋用就行了——这就是我理解的组件。
那么如何实现组件呢?我们可以用c++的虚类来理解接口.每个接口实现了许多函数,许多接口便组成了组件...bulabulabula
所有的com接口都实现了IUnknown接口(接口中的函数都必须实现,java中是这样),该接口有三个方法:QueryInterface、AddRef、Release,com接口的前三个函数必定是这三个,下面介绍这三个函数的功能
QueryInterface(const IID&iid,void**ppv):客户用来通过此函数来查询某个组件是否支持某个特定的接口,若支持则返回指向此接口的指针,否则返回错误代码;第一个参数表示“接口标识符”,标示接口所需的常量,另一个参数存放接口地址的指针;返回HRESULT可用相应的宏判断返回值的意义;当接口不被支持的时候*ppv应该为NULL,下面是一些代码和注释...
#include <iostream> #include <objbase.h> using namespace std; void trace(const char* msg) { cout << msg << endl ;} // Interfaces 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)/*存ä?放¤?地Ì?址¡¤的Ì?指?针?void* 可¨¦以°?包㨹容¨Y任¨?意°a类¤¨¤型¨ª*/ { if (iid == IID_IUnknown) { trace("QueryInterface: Return pointer to IUnknown.") ; /* static_cast < type-id > ( expression ) ? ?该?运?算?符¤?把ã?expression转Áa换?为atype-id类¤¨¤型¨ª,ê?但Ì?没?有®D运?行D时º¡À类¤¨¤型¨ª检¨¬查¨¦来¤¡ä保À¡ê证¡è转Áa换?的Ì?安ã2全¨?性?。¡ê它¨¹主¡Â要°a有®D如¨?下?几?种?用®?法¤¡§:êo ? ?①騴用®?于®¨²类¤¨¤层?次ä?结¨¢构1中D基¨´类¤¨¤(ꡧ父?类¤¨¤)ê?和¨ª派¨¦生¦¨²类¤¨¤(ꡧ子Á¨®类¤¨¤)ê?之?间?指?针?或¨°引°y用®?的Ì?转Áa换?。¡ê ? ?进?行D上¦?行D转Áa换?(ꡧ把ã?派¨¦生¦¨²类¤¨¤的Ì?指?针?或¨°引°y用®?转Áa换?成¨¦基¨´类¤¨¤表À¨ª示º?)ê?是º?安ã2全¨?的Ì?;ê? ? ?进?行D下?行D转Áa换?(ꡧ把ã?基¨´类¤¨¤指?针?或¨°引°y用®?转Áa换?成¨¦派¨¦生¦¨²类¤¨¤表À¨ª示º?)ê?时º¡À,ê?由®¨¦于®¨²没?有®D动¡¥态¬?类¤¨¤型¨ª检¨¬查¨¦,ê?所¨´以°?是º?不?安ã2全¨?的Ì?。¡ê ? ?②騲用®?于®¨²基¨´本À?数ºy据Y类¤¨¤型¨ª之?间?的Ì?转Áa换?,ê?如¨?把ã?int转Áa换?成¨¦char,ê?把ã?int转Áa换?成¨¦enum。¡ê这a种?转Áa换?的Ì?安ã2全¨?性?也°2要°a开a发¤¡é人¨?员¡À来¤¡ä保À¡ê证¡è。¡ê ? ?③é?把ã?空?指?针?转Áa换?成¨¦目?标À¨º类¤¨¤型¨ª的Ì?空?指?针?。¡ê ? ?④騹把ã?任¨?何?类¤¨¤型¨ª的Ì?表À¨ª达ä?式º?转Áa换?成¨¦void类¤¨¤型¨ª。¡ê ?注Á¡é意°a:êostatic_cast不?能¨¹转Áa换?掉Ì?expression的Ì?const、¡évolitale、¡é或¨°者?__unaligned属º?性?。¡ê */ *ppv = static_cast<IX*>(this) ;//*ppv放¤?的Ì?是º?地Ì?址¡¤... } 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() ; // See Chapter 4. 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: Ask for an unsupported interface.") ; IZ* pIZ = NULL ; hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ) ; if (SUCCEEDED(hr)) { trace("Client: Succeeded in getting interface 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* pIUnknownFromIY = NULL ; hr = pIY->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromIY) ; if (SUCCEEDED(hr)) { cout << "Are the IUnknown pointers equal? " ; if (pIUnknownFromIY == pIUnknown) { cout << "Yes, pIUnknownFromIY == pIUnknown." << endl ; } else { cout << "No, pIUnknownFromIY != pIUnknown." << endl ; } } // Delete the component. delete pIUnknown ; return 0 ; }