•인터페이스 중에서 최상위 인터페이스이며, 모든 COM 컴포넌트가 상속 받아야 할 Interface
//unknwn.h 파일에 선언됨
interface IUnknown
{
virtual HRESULT __stdcall QueryInterface(REFIID riid, void **ppv)=0; //Interface 얻어오기 !!
virtual ULONG __stdcall AddRef()=0; //개체 참조 카운트 증가 !!
virtual ULONG __stdcall Release()=0; // 개체 참조 카운트 감소 !!
}
// __stdcall : 지역변수를 호출된쪽에서 소거!
// __declspec : 지역변수를 호출하는쪽에서 소거!
- 개발자에 의해 구성되는 Component에서 상속 받아 재 정의 할 추상기본 클래스
- 최상위 인터페이스인 IUnknown을 반드시 상속 받아야 함
- C++에서는 다중 상속이 가능(MFC 에서는 불가)
interface ICalcu : IUnknown
{
virtual int __stdcall Sum() = 0;
};
GUID - 고유한 컴포넌트임을 알려주는 키값 (Guigen을 이용해 생성한다)
typedef GUID IID;
typedef GUID CLSID;
#define REFIID const IID &
#define REFCLSID const CLSID &
•IID 및 CLSID는 GUID를 재정의 하여 사용하는 것 뿐이다
// {7D1DA4D3-2DD8-4317-937D-157BF19DE48C}
static const IID IID_ISetVal =
{ 0x7d1da4d3, 0x2dd8, 0x4317, { 0x93, 0x7d, 0x15, 0x7b, 0xf1, 0x9d, 0xe4, 0x8c } };
// {1BA9514E-9303-4c4d-948A-D1EAA0932A82}
static const IID IID_ICalcu =
{ 0x1ba9514e, 0x9303, 0x4c4d, { 0x94, 0x8a, 0xd1, 0xea, 0xa0, 0x93, 0x2a, 0x82 } };
•IID 값은 IUnknown의 QueryInterface 구현부에서 다수의 사용자 인터페이스를 구별하여 올바른 포인터 값을 반환할 수 있도록 한다.
Interface Inheritance
class CInsideCom : public ISetVal, ICalcu
{
•Interface는 구성하고자 하는 Component 클래스에 의해 상속될 수 있다.
•Component 클래스는 상속된 Interface의 Pure Virtual Function에 대하여 그 구현을 제공 해야 한다.
•이렇게 상속된 Interface는 객체 생성시 Virtual Function Table이 구성된다.
//IUnknown Interface
virtual HRESULT __stdcall QueryInterface(REFIID riid, void **ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
//ISetVal Interface
virtual void __stdcall SetXY(int, int);
//ICalcu Interface
virtual int __stdcall Sum();
•ISetVal과 ICalcu 인터페이스를 상속 받았고, 순수가상함수에 대하여 재정의 하기 위한
- Qurryinterface 에게 IID_X키 값을 가진 놈에 대한 포인터를 가져와라.
IUnknown* CreateInstance()
{
IUnknown *pI=NULL;
pI = static_cast<ISetVal*>(new CInsideCom());
return pI;
}
- Component를 사용하기 위해서는 객체를 생성해야 한다.
-객체 생성후 클라이언트에서는 Component객체의 IUnknown 인터페이스 포인터가 필요한데, 이는 개발자가
구성한 인터페이스 접근하여 데이터를 조작하기 위한 유일한 수단이기 때문이다.
Com 객체 사용 예제
IUnknown* pIUnknown = NULL;
ISetVal* pISetVal = NULL;
ICalcu* pICalcu = NULL;
pIUnknown = CreateInstance();
if(pIUnknown)
{
HRESULT hr = pIUnknown->QueryInterface(\
IID_ISetVal,(LPVOID*)&pISetVal);
if(SUCCEEDED(hr)) {
pISetVal->SetXY(3,4);
hr = pIUnknown->QueryInterface(\
IID_ICalcu, (LPVOID*)&pICalcu);
cout << "The Sum of x + y : " << pICalcu->Sum() << endl;
}
}
- SUCCEEDED 매크로를 사용하여 함수의 성공 여부를 확인할 수 있다.
- FAILED 매크로를 사용하여 실패
'API & MFC > MFC & COM' 카테고리의 다른 글
컴포넌트 생성및 접근 (0) | 2010.03.15 |
---|---|
Registry (0) | 2010.03.15 |
COM이론(Component Object Model) (0) | 2010.03.12 |
메모리 비트맵 (0) | 2010.03.11 |
SDK와 MFC (0) | 2010.03.11 |