2010. 3. 13. 10:59
Iunknown Interface
 
인터페이스 중에서 최상위 인터페이스이며, 모든 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 : 지역변수를 호출하는쪽에서 소거!
 
QueryInterface : Component가 구현하고 있는 인터페이스의 포인터를 얻어오는 역할 수행, 클라이언트 입장에서 객체에 접근하기 위한 중요한 기능
AddRef : 메모리 상의 Component 객체의 참조 카운터를 증가 시킴
Release : 메모리 상의 Component 객체의 참조 카운터를 감소 시킴 


User define Interface 

- 개발자에 의해 구성되는 Component에서 상속 받아 재 정의 할 추상기본 클래스


- 최상위 인터페이스인 IUnknown을 반드시 상속 받아야 함

 

- C++에서는 다중 상속이 가능(MFC 에서는 불가)

 

interface ICalcu : IUnknown

{

           virtual int __stdcall Sum() = 0;

};

 

  

 

GUID - 고유한 컴포넌트임을 알려주는 키값 (Guigen을 이용해 생성한다)

 CLSID - CoClass의 GUID ,  IID - 인터페이스의 GUID 

  

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

{

 public:

 

 

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 인터페이스를 상속 받았고, 순수가상함수에 대하여 재정의 하기 위한

  

 CInsideCom클래스는 아래와 같이 인터페이스(가상함수테이블)가 구성되있겠다.

             QurryInterface, AddRef, ,Relese, Sum, ISetVal

 Qurrrinterface 를 통해서만 외부와 통신 할 수 있다.

- Qurryinterface 에게 IID_X키 값을 가진 놈에 대한 포인터를 가져와라.

 

 

 Com 객체 생성


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
Posted by 아몰라