*이 포스팅은 개인 학습을 위해 내용을 정리한 것이 목적입니다.
1. 포함의 원리
- 포함은 통합과 달리 외부 컴포넌트가 내부 컴포넌트를 생성부터 소멸까지 관리한다. 클라이언트에서는
외부 컴포넌트를 통해 내부 컴포넌트에 접근(내부로 직접 접근이 안됨)
- 포함의 사용목적은 컴포넌트가 만들어진 경우 재활용을 통해 개발주기를 단축할 수 있어서임. 포함은 현
재 있는 컴포넌트를 한겹 감싸서 이용하고자 할 때 사용한다.
- 포함과 통합의 선택
포함: 내부 컴포넌트의 기능의 강화 및 수정이 필요할 때 유리
통합: 내부 컴포넌트를 바로사용할 수 있을 때 유리
- 포함의 과정
1) 외부컴포넌트의 DllGetClassObject() 호출 - 외부 컴포넌트의 클래스팩토리 생성 2) 외부 컴포넌트의 클래스팩토리에서 파생 클래스를 생성 3) 파생 클래스에서 내부 컴포넌트의 CoCreateInstance() 호출 4) 내부컴포넌트의 인터페이스를 생성하고 메모리로 로딩 5) 4)의 생성된 인터페이스를 받아서, 외부 컴포넌트의 클래스에서 내부 컴포넌트를 사용할 수 있음 |
2. 통합의 원리
- 통합 : 내부 컴포넌트로 호출을 포워딩. 클라이언트가 내부 컴포넌트에 포함된 인터페이스를 직접호출
- QueryInterface()에서 내부 컴포넌트에 대한 호출이 발생시
-> 내부 컴포넌트의 포인터를 구한 후, 내부컴포넌트에 QueryInterface()를 호출한다.
- 통합에서의 CoCreateInstance
IUnknown* pUnknownOuter = this; HRESULT hr = ::CoCreateInstance( CLSID_COMPONENT, pUnknownOuter, CLSCTX_INPROC_SERVER, IID_UNKNOWN, (void**)&m_pUnknownInner); |
CoCreateInstance()에서 두번째 인자 pUnknownOuter를 전달하는 이유
-> 내부 컴포넌트는 외부 Unknown에게 IUnknown인터페이스 사용의 위임을 위해서.
- 내부 컴포넌트를 숨기면서 외부컴포넌트의 IUnknown만으로 클라이언트가 접속할 수 있도록 할것
1) 통합을 위한 Unknown인터페이스
내부 컴포넌트가 외부 Unknown을 사용할 수 있게 하려면 직접 외부 Unknown을 호출. 이를 위해서는 내
부 컴포넌트가 외부 Unknown을 가지고 있어야 함.
2) 내부 컴포넌트의 IUnknown구성
- 내부컴포넌트의 IUnknown을 그냥 사용하면 참조에 문제가 생김.
외부에서 내부컴포넌트의 인터페이스를 호출하면, 내부 컴포넌트의 참조계수가 증가한다. 그러나 클라
이언트에서 Release를 호출하여 참조계수를 감소시킬 방법이 없다.
-> 통합에서는 외부 컴포넌트에서 관리할 수 있도록 내부컴포넌트의 IUnknown멤버변수를 두고, 내부
에서는 외부컴포넌트의 IUnknown을 가져 모든것을 외부에 위임할 수 있게 함.
- INondelegatingUnknown : 내부 컴포넌트에서 관리를 위한 인터페이스가 필요하여 생성.
struct INondelegatingUnknown { virtual HRESULT __stdcall NondelegatingQueryInterface(const IID&, void**) = 0; virtual ULONG __stdcall NondelegatingAddRef() = 0; virtual ULONG __stdcall NondelegatingRelease() = 0; }; |
위 인터페이스는 IUnknown을 대신하여 모든일을 처리할 수 있도록 만들기 위함.
->내부 컴포넌트의 참조계수는 모두 외부 컴포넌트에서 처리하도록 만들었다.
내부 컴포넌트의 IUnknown의 멤버함수에서 작업하던 내용을 INondelegatingUnknown의 멤버함수에서
수행하도록 만들었고, 인터페이스로 캐스팅 할 때, IUnknown이 아닌 INondelegatingUnknown로 캐스팅
- 오로지 외부 컴포넌트만이 내부 컴포넌트의 INondelegatingUnknown획득 가능
- 통합을 지원하고자 할 경우 내부 컴포넌트는 실제적으로 두 개의 IUnknown인터페이스를 지원.
*잡담 : MSDN을 찾아보니 INonDelegatingUnknown이 있다!.
목적에 보면.. 같은 COM객체에 대해 nondelegating과 delegating을 지원하는 IUnknown의 버전이라고.. 여기서 설명된 것과의 차이는 무얼까?
출처 - COM Bible
댓글