<COM 기술을 이용하는 시나리오>
1. '밥짓는 로봇'이 필요하여 로봇을 하나 생산하도록 결정.
2. '공장'에 '밥 짓는 용도'의 로봇 생산을 의뢰. 이때 '로봇 생산에 사용할 원료'를 지정해 줌.
공장은 로봇을 생산한 후 로봇과 함께 '밥 짓는 명령'을 지시할 수 있는 '리모콘'을 전달.
3. '리모콘의 밥 짓기 버튼'을 눌러 밥 짓는 명령을 지시하고, 로봇은 밥을 짓는다.
4. 리모콘에는 밥 짓기 버튼 외에 '기본 용도' 라고 쓰여진 공간에 세 개의 또 다른 버튼이 있다.
세 개의 버튼에는 각각 '묻기 버튼', '활성화 버튼' 그리고 '비활성화 버튼'이라는 이름이 붙어있음.
5. 밥짓는 로봇에게 쉬는 동안 청소도 시켰으면 하는 바람이 생겼다. 리모콘의 '묻기 버튼'을 눌러 로봇에게
'청소 용도'로 사용할 수 있는지 물어본다. 청소도 할 수 잇으면 청소 명령을 지시할 수 있는 리모콘을 전달.
6. 리모콘을 복제하여 필요한 가족에게 전달한다. 리모콘을 전달받은 사람은 '리모콘의 활성화 버튼'을 눌러
로봇에게 자신이 사용하겠다는 의사를 전달함.
7. 로봇이 더 이상 필요 없는 사람은 '리모콘의 비활성화 버튼' 을 누른다. 이때 활성화된 리모콘이 하나도
없으면 로봇은 자신을 사용하는 사람이 더 이상 없음을 알고 스스로 자폭하여 사라짐.
<시나리오 용어에 해당하는 COM 기술 용어>
공장 - COM 팩토리 컴포넌트
생산에 사용할 원료 - COM 컴포넌트
로봇 - COM 객체
로봇 생산 - COM 객체 생성
로봇 자폭 - COM 객체 소멸
용도 - COM 인터페이스
밥 짓는 용도 - 밥 짓는 기능을 갖는 COM 인터페이스
청소 용도 - 청소 기능을 갖는 COM 인터페이스
밥 짓는 로봇 - 밥 짓는 기능의 COM 인터페이스를 갖고 있는 COM 객체
리모콘 - COM 인터페이스 포인터
리모콘 버튼 - COM 인터페이스 내의 함수
리모콘의 특정 버튼 누르기 - COM 인터페이스의 해당 함수 호출
기본 용도 - 모든 COM 인터페이스의 기본 기능의 IUnknown 인터페이스
리모콘의 듣기 버튼 - IUnknown 인터페이스의 QueryInterface()함수
리모콘의 활성화 버튼 - IUknown 인터페이스의 AddRef() 함수
리모콘의 비활성화 버튼 - IUknown 인터페이스의 Release() 함수
1. 로봇 생산과 CoCreateInstance() 함수
- 공장에 생산을 의뢰할 때는 CoCreateInstance() API 함수를 사용.
- 첫번째 매개변수는 원료를 지정하는 항목으로 COM 컴포넌트의 CLSID(class ID)를 입력한다.
- 네번째 매개변수에는 사용할 용도를 기술. 즉 시나리오에서의 밥 짓느 ㄴ용도로 사용할 로봇.
- 다섯번째 매게변수는 리모콘을 얻어오는 곳. 리모콘을 건네받아야 하므로 포인터를 먼저 건네준 후 건네받음.
- 'COM 컴포넌트'란 일종의 C++ 클래스.
- COM 컴포넌트는 특정 내용을 모두 구현해 놓은 대상이지만 메모리에 존재하지 않는 개념.
- COM 객체는 COM 컴포넌트를 new 연산자 등을 이용해 직접 메모리에 생성해둔 모듈을 의미.
- COM 인터페이스도 COM 컴포넌트처럼 추상적인 개념으로, COM 컴포넌트는 이 COM 인터페이스를 구현한 모듈.
- COM 컴포넌트가 COM 객체로 구체화되면 그 COM 인터페이스 포인터를 얻을 수 있으며, COM 인터페이스 포인터는 COM 객체에서 해당 인터페이스를 구현한 부분을 가리킴.
-> COM 컴포넌트나 COM 인터페이스 자체에 명령을 내리는 것은 있을 수 없으며, COM 객체나 COM 인터페이스 포인터에 명령을 내린다는 것이 올바른 표현이다.
2. 리모콘 버튼과 인터페이스 함수 호출
- 리모콘은 인터페이스 포인터를 의미하고, 리모콘 버튼은 그 인터페이스 내에 있는 함수를 의미한다.
- 인터페이스 포인터를 통해 직접 함수를 호출한다.
- 함수를 호출하는 순간 원하는 작업이 수행되고, 함수의 특징에 따라 그 결과를 전달받게 된다.
3. 기본 명령과 IUnknown 인터페이스
- 기본 용도는 COM 기술에서 IUnknown 인터페이스에 해당된다.
- COM 인터페이스라고 하면 반드시 이 인터페이스를 상속받아야 하기 때문에, 사용자는 모든 COM 인터페이스에 대해 IUnknown 인터페이스를 기대할 수 있다.
- IUnknown 인터페이스는 QueryInterface(), AddRef(), Release() 함수를 포함하고 있으며, 이 함수들은 각각 묻기 버튼, 활성화 버튼, 비활성화 버튼에 해당한다.
4. 묻기 버튼과 QueryInterface() 함수
- QueryInterface() 함수를 이용해 필요한 용도를 수행할 수 있는지 물어본다.
- 만약 COM 객체가 그러한 용도를 수행할 수 있다면 그에 맞는 인터페이스 포인터를 건네줄 것이고, 그렇지 않다면 오류 코드를 리턴하면서 아무 것도 건네주지 않을 것이다.
- QueryInterface() 함수를 호출하면서 첫번째 매개변수에 용도를, 두번재 매개변수에 그 용도에 해당하는 리모콘의 포인터를 입력. (CoCreateInterface() 함수에서 사용했던 네번째, 다섯번째 매개변수와 일치함)
5. 활성화 버튼과 AddRef() 함수
- 복제된 리모콘은 활성화 버튼을 누른 후에야 로봇에게 다른 명령을 수행할 수 있다.
- 새로운 인터페이스를 선언한 후 리모콘을 복제하고, 복제된 인터페이스 포인터도 결국 같은 메모리 공간을 가리키므로 그대로 명령을 수행할 수 있다.
- 어디서 얼마나 많은 인터페이스 포인터를 복제하여 COM 객체를 소멸시킬 시기를 알 수 없게 되므로, COM 기술에서는 COM 객체를 자동소멸 시키는 방식을 채택.
- COM 객체가 관리하는 개수를 '참조 개수'라고 하며, 참조 개수가 0일대 자동 소멸한다.
- AddRef() 함수는 'Add Reference count', Release() 함수는 'Release reference count' 라는 의미.
- AddRef() 함수의 호출은 매개변수가 없기 때문에 간단하다.
- CoCreateInstance() 나 QueryInterface() 함수를 통해 받은 인터페이스는 이미 참조 개수가 증가된 상태이기 때문에, 따로 AddRef() 함수를 사용할 필요가 없다.
6. 비활성화 버튼과 Release() 함수
- 비활성화 명령이 로봇에게 전달될 때마다 로봇은 리모콘과의 연결을 끊고 아직 남아 있는 연결이 있는지 확인.
- 남아있는 연결이 있다면 로봇은 계속 명령에 대기하지만, 남은 연결이 하나도 없다면 로봇은 자폭을 결정하고 소멸하게 된다.
- COM 객체는 Release() 함수를 호출하여 참조 개수가 0이 될때 delete 연산자 등을 이용해 스스로 소멸.
- AddRef() 함수와 Release() 함수는 반드시 짝을 이루어 사용된다.
7. HRESULT와 매크로
- COM 기술에서 대부분의 함수는 HRESULT라는 자료형을 리턴.
- 함수 호출의 성패 여부를 알아내기 위해 최상위 비트를 확인 (0이면 성공, 1이면 실패 의미)
- 대부분 미리 정해놓은 HRESULT 값을 사용.
- 성공한 코드는 'S_(SUCCESS)'를 포함하고, 실패한 코드는 'E_(ERRPR)'를 포함한다.
- 정의된 코드값을 보면 성공한 코드는 대부분 0으로 시작하고, 오류 코드는 모두 8로 시작한다.
[출처 : DirectShow 멀티미디어 프로그래밍 (한빛미디어)]
'ATL / WTL' 카테고리의 다른 글
[개발 히스토리] ATL 로 BHO 를 만들면서... (0) | 2008.12.20 |
---|---|
ATL COM을 이용한 ICommand만들기(3) (0) | 2008.12.20 |
ATL COM을 이용한 ICommand만들기(2) (0) | 2008.12.20 |
ATL COM을 이용한 ICommand만들기(1) (0) | 2008.12.20 |
CoInitialize(NUUL) ?? (0) | 2008.12.20 |