COM(Component Object Model)
- 가상함수 테이블을 메모리게 구축하고 Virtual Table을 통해 함수를 호출하는 표준 정의
- 인터페이스(접근방법)와 구현(캡슐화)의 분리
- 모든 COM 인터페이스는 IUnknown의 AddRef(), Release(), QueryInterface() 함수로 시작
- 인터페이스 : 개체와 클라이언트간의 규약
- 사용자와 소프트웨어가 따로 사용하는 이름이 존재
- 일반적으로 인터페이스명은 I로 시작
- 모든 인터페이스는 GUID(Globally Unique Identification)를 가짐(=IID)
- IID : 128 bit 구조체 형식, IP와 시간에 대한 알고리즘으로생성하므로 세계에서 유일한 ID
- Implementation에서는 강제로 특정언어, 표기법을 명령하지 않음
- IDL(Interface Definition Language)가 주로 사용
- 위치 투명성, 언어 독립성, 강한 객체지향성, 높은 재사용성, COM 버전보장
- DLL, EXE, OCX(COM 규약을 따르는 VBX의 후속버전) : 기능 수행이 가능한 바이너리(언어 독립성 제공), COM 객체의 인스턴스 정보 포함
- 레지스트리에 정보를 기록하여 사용하므로 어디에 위치해 있어도 사용 가능
- In-Process Server : DLL, OCX 형태로 제공, 클라이언트 프로세스에 포함되어 실행, 클라이언트의 메모리 주소로 Access하므로 처리속도가 빠름, COM 서버 자체에 문제가 발생시 클라이언트 메모리도 영향을 받음, 같은 PC에 존재해야 한다는 제약조건
- Out-Process Server : EXE 형태로 제공, COM 서버를 사용하는 클라이언트가 서비스 요청시 윈도우에 등록된 COM EXE 서버를 자동으로 실행하고 필요없을 경우 스스로 종료, 클라이언트-서버 통신은 COM에서 제공하는 특정 프로토콜을 이용, COM 서버에서 발생하는 문제는 클라이언트에 영향을 미치지 않음, In-Process Server와 DCOM의 중간 처리속도
- DCOM : COM이 다른 머신에 위치하여 분산 컴퓨팅이 가능, 컴퓨터의 리소스를 분산하여 활용 가능, 네트워크의 부하가 증가
- In-Process Server, Out-Process Server, DCOM 모두 동일한 방식으로 구현
- 모든 COM 함수는 HRESULT를 리턴
COM의 Life-Cycle
- COM 자신이 스스로 자신을 메모리에 로드 & 해제 해야함(참조 카운트 이용)
- IUnknown 인터페이스를 상속받아서 구현
* AddRef() : COM 서비스를 참조하는 프로세스의 개수 증가
* Release() : COM 서비스를 참조하는 프로세스의 개수 감소, 0이 되면 스스로 메모리에서 해제
* QueryInterface() : 인터페이스를 구하기 위하여 사용, COM 객체를 로드하여 인터페이스를 얻어 그에 속한 함수를 호출
COM의 리턴타입
- S_OK : Boolean TRUE 값, 함수가 성공
- NOERROR : S_OK와 동일
- S_FALSE : S_OK와 반대, Boolean FALSE 값, 함수가 실패
- E_UNEXPRCTED : 치명적인 실패
- E_NOTIMPL : 멤버 함수에 구현 코드가 포함되어 있지 않음
- E_OUTOFMEMORY : 필요한 메모리를 할당할 수 없음
- E_INVALIDARG : 하나 혹은 그 이상의 인자가 타당하지 않음
- E_NOINTERFACE : 요청한 인터페이스를 지원하지 않음
- E_POINTER : 타당하지 않은 포인터
- E_HANDLE : 타당하지 않은 처리
- E_ABORT : 작동 중지
- E_FAIL : 특정하지 않은 실패
- E_ACCESSDENIED : 일반적 접근이 금지된 에러
COM의 가상함수 정의 매크로
- STDMETHOD(method)
- STDMETHOD_(type, method)
- STDMETHODIMP(method)
- STDMETHODIMP_(type, method)
인터페이스
- COM에서 서로 다른 객체를 연결하는 연결 고리
- #define interface struct
- 변화에 의한 손상으로부터 시스템 보호 가능
- 서로 다른 컴포넌트에 대해 클라이언트가 동일한 방법으로 접근 가능
- 함수에 대한 포인터 배열을 포함하는 메모리 구조
순수 가상 함수
- 기본 클래스에서 가상함수의 속성이 정의되어 있지 않은 함수
- Function = 0;
추상 기본 클래스
- 상속을 통해 파생된 클래스에서만 인스턴스 생성이 가능
- 추상 기본 클래스는 오브젝트 생성이 불가능
Virtual Table
- 함수의 번지값이 연속으로 저장되어 있는 배열
모듈화
- 프로그램의 분리를 통해 개발 기간의 단축 효과
컴포넌트
- 자체 독립성(여러개의 모듈의 집합)
IUnknown 인터페이스의 기본 함수
- AddRef()
* IUnknown 인터페이스에 포함, COM 컴포넌트 생성시 카운트 1 증가
- Release()
* IUnknown 인터페이스에 포함, COM 컴포넌트 작업이 완료되면 카운트 1 감소
- QueryInterface()
* IUnknown 인터페이스에 포함, 유일성을 보장받기 위한 함수
* 컴포넌트 인스턴스는 항상 동일한 IUnknown을 가짐, 항상 클라이언트는 같은 값의 IUnknown 인터페이스의 포인터를 가짐
* 동일한 컴포넌트 대해 한 번 획득한 인터페이스는 계속 획득 가능, 인터페이스는 시간에 따라 변하지 않음
* 이미 획득한 인터페이스로 다시 동일한 인터페이스 획득 가능
* 인터페이스를 역으로 획득 가능
* 인터페이스 사용 후 반드시 해제
* 인터페이스 x로부터 y를 획득하고 y로부터 z를 획득하였을 경우 x로부터 z를 획득 가능
HRESULT
- 오류코드 관련 정보, 사용자 정의 코드 생성
- COM에서는 HRESULT를 통해 상태를 사용자에게 전달
- winerror.h에 정의
- 코드구성
* Serverity Code : HRESULT의 성공/실패 상태(30 ~ 31 bit에 포함)
* Facility Code : 반환코드값의 형식에 관한 정보(16 ~ 27 bit에 포함)
* Return Code : 함수의 반환값에 대한 정보(0 ~ 15 bit에 포함)
- 성공/실패 여부를 판단하는 매크로 : FAILED(), SUCCEEDED()...
- FormatMessage() 함수를 이용하여 에러 메시지 추출
- 임의로 코드를 정의할 수 있는 매크로 : MAKE_HRESULT()
GUID (Globally Unique Identifier)
- 모든 인터페이스의 유일성을 보장
- typedef GUID IID
- 클라이언트의 네트워크 카드 정보 이용(Unique Information)
- 네트워크 카드가 없을 경우 60 bit의 타임 스탬프 이용(100% 유일성이 보장 안되므로 UUIDGEN에서 경고 메시지 발생)
- 비교방법 : ==연산자(objbase.h), IsEqualGUID(), IsEqualIID(), IsEqualCLSID() 이용
- 레퍼런스만으로 값 전달 가능(const IID& riid = REFIID riid)
IDL(Interface Definition Language)
- 인터페이스의 정의에 대한 기술어
- 인터페이스와 함수를 정의하는 언어
- 언어의 독립성을 보장하기 위한 인터페이스 정의어
- COM 객체에 대한 접근 방법만을 제공, 내용은 없음
- MS에서 IDL을 위한 MIDL 컴파일러 제공
* a.idl을 컴파일 -> a.h(인터페이스 정의를 포함), a_i.c(GUID를 포함), a.tib(C, C++ 외의 다른 언어를 위한 바이너리 형태의 라이브러리), a_p.c(Proxy 코드), a.data.c(Stub 코드)
* Proxy, Stub 코드는 Local COM, Distributed COM을 사용할 때 필요
* Proxy : 클라이언트 요청을 수집 및 정리하여 COM 서비스(Stub)에게 전달
* Stub : Proxy가 보낸 정보를 해석하여 실제 서비스에게 전달하고 그 응답을 다시 Proxy에게 전달
* Marshaling : Proxy와 Stub의 전반적인 처리 과정
IClassFactory
- COM 생성에 관련된 인터페이스
- CreateInstance() : 객체를 생성하는 함수
- LockServer() : 동기화의 일종, 객체를 생성하는 동안 서버가 메모리에서 내려가거나 하는 경우를 예방하기 위한 함수
'COM, ATL' 카테고리의 다른 글
컴포넌트 관련 define 문 (0) | 2008.08.13 |
---|---|
Silan Liu의 COM과 ATL.html (0) | 2008.08.13 |
REGSVR32 사용법 (0) | 2008.08.12 |
Process/Thread/Apartment (0) | 2008.08.02 |
How to Use IMessageFilter (1) | 2008.08.02 |
Single Threaded Apartment(STA)에서 고려해야 할 몇가지 것들 (0) | 2008.08.02 |
Apartment Types (0) | 2008.07.30 |