在很久以前,就因为项目的需求,接触到了组件的概念,但是由于各种原因(主要还是自己太懒...)没有系统的学习和理解组件.进几天项目空闲下来,我魔兽世界也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 ;
}
浙公网安备 33010602011771号