COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가?
본 게시물은 ‘codeproject.com’에 게시된 글 ‘Introduction to COM - What It Is and How to Use It.’을 번역한 것입니다.
원 게시물은 https://www.codeproject.com/Articles/633/Introduction-to-COM-What-It-Is-and-How-to-Use-It에 게재되어 있습니다. 최대한 원문에 적힌 의도를 반영하고자 하였으나, 우리말로 읽었을 때 보다 자연스럽게 하고자 부득이 어순과 어휘를 조정한 부분도 있음을 양해 바랍니다.
또한 본 게시물에서 언급하고 있는 예제 소스 코드는 Visual C++ 6.0을 기준으로 작성되어 있기 때문에 후속 버전의 Visual Studio(또는 Visual Studio .NET)에서 자동 생성되는 COM 코드와는 다소 차이가 있음을 감안하고 읽으시기 바랍니다.
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (1)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (2)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (3)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (4)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (5)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (6)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (7)
- COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (8) [完]
HRESULT 다루기
필자는 SUCCEEDED
와 FAILED
매크로를 사용하여, 오류를 처리하는 방법 몇 가지를 간단하게 언급하였습니다. 지금부터는 COM 메소드가 반환하는 HRESULT
를 가지고 좀 더 자세히 다루어 보겠습니다.
HRESULT
는 32비트 부호 있는 정수입니다. 음수가 아닌 값은 성공하였음을 나타내고, 음수 값은 실패를 나타냅니다. HRESULT
는 (1) 성공 또는 실패를 나타내는 ‘심각도 비트(severity bit)’, (2) ‘패실리티 코드(facility code)’, (3) ‘상태 코드(status code)’의 세 가지 필드를 갖습니다(역자: facility code의 적절한 우리말을 찾지 못하여 그냥 그대로 적었습니다).
‘facility’는 HRESULT
가 유래된 컴포넌트 또는 프로그램을 의미합니다. 마이크로소프트는 다양한 컴포넌트에 facility code를 배정하고 있습니다. COM은 이 중 하나이고, 작업 스케줄러도 이 중 하나입니다. ’코드’는 16비트 필드이며 그 자체로 어떤 의미를 내재하지는 않습니다. 즉, 코드는 숫자가 될 수도 있고, GetLastError
가 반환하는 값과 비슷하게 어떤 의미가 될 수도 있는데 이는 그때그때 다릅니다.
여러분이 winerror.h
파일을 살펴본다면, 수 많은 HRESULT
들이 적혀 있음을 알 수 있습니다. 그리고 이들의 이름은 [facility]_[severity]_[description]
의 구조로 되어 있음을 알 수 있습니다. 아무 컴포넌트에서나 반환 가능한 일반적인 HRESULT
는 E_OUTOFMEMORY
와 같이 그 이름에 facility를 갖고 있지 않습니다.
예를 들어,
REGDB_E_READREGDB
- 패실리티(facility)가
REGDB
(레지스트리 데이터베이스), 심각도는E
(오류), 코드는 이 경우 상황을 설명하는READREGDB
입니다. 조합하면 중대한 오류로서, 데이터베이스를 읽지 못함을 의미합니다. S_OK
- 패실리티(facility)는 일반(generic)이고, 심각도는
S
(성공)입니다.OK
는 현 상황의 상태를 나타내며, 조합하면 모든 것이 정상이라는 뜻입니다.
다행히도, winerror.h
를 열어놓지 않아도 HRESULT
의 의미를 찾아볼 수 있습니다. 윈도우 운영체제에 내장된 패실리티(facility)는 ‘오류 값 찾기 도구(Error Lookup Tool)’를 이용하여 찾을 수 있습니다.
여러분이 CoCreateInstance
를 호출하기 전에 CoInitialize
호출하는 것을 깜빡하였다면, CoCreateInstance
는 0x800401F0
을 반환할 것입니다. 독자 여러분은 Error Lookup 도구에 이 값을 검색할 것이고, “CoInitialize가 호출되지 않았습니다.”라는 설명을 보게 됩니다.
여러분은 또한 디버거에서 HRESULT
설명을 찾을 수 있습니다. 여러분의 HRESULT
형 변수를 hres
라고 이름 붙였다면, 변수 감시 창(Watch 창)에 “hres,hr
”을 입력함으로써 해당 변수의 값을 볼 수 있습니다. “,hr
”은 Visual C++에게 그 변수의 값을 HRESULT
로 간주하고 이에 해당하는 텍스트 설명으로 보여주도록 지정합니다.
참고자료
《Essential COM》 by Don Box (ISBN 0-201-63446-5)
여러분이 한 번쯤은 알고 싶어하실 COM 사양과 IDL(interface, definition language)에 대한 모든 것이 나와 있습니다. 특히 처음 두 챕터에는 COM 스펙과 그리고 이것이 해결하고자 했던 문제에 대해 자세히 나와 있습니다.
《MFC Internals》 by George Shepherd and Scot Wingo (ISBN 0-201-40721-3)
MFC의 COM 지원에 대해 심도 깊은 내용을 포함하고 있습니다.
《Beginning ATL 3 COM Programming》 by Richard Grimes 외 공저 (ISBN 1-861001-20-7)
이 책은 ATL을 사용하여 여러분이 직접 COM 컴포넌트를 개발할 경우에 대하여 상세히 적고 있습니다.