^(코딩캣)^ = @"코딩"하는 고양이;

COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (5)

API/COM
2020. 10. 4. 13:16

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 코드와는 다소 차이가 있음을 감안하고 읽으시기 바랍니다.

  1. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (1)
  2. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (2)
  3. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (3)
  4. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (4)
  5. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (5)
  6. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (6)
  7. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (7)
  8. COM의 소개(파트 1) – COM이 무엇이며, 어떻게 사용하는가? (8) [完]

 

기본 인터페이스 – IUnknown

모든 COM 인터페이스는 IUnknown으로부터 파생됩니다. 이 인터페이스의 이름은 다소 오해의 소지가 있는데, 사실 이것은 ‘알 수 없는(unknown)’ 인터페이스라는 뜻이 아닙니다. 모든 COM 객체는 IUnknown을 구현하고 있기 때문에 여러분이 어떤 COM 객체에 대해 IUnknown 포인터를 가지고 있다면, 여러분은 그 포인터가 정확히 어떤 형식의 객체를 가리키고 있는지 알 수 없다는 것을 이 이름이 의미하고 있습니다.

IUnknown은 세 가지 메소드들을 갖습니다.

AddRef
COM 객체에게 레퍼런스 카운트를 증가할 것을 알려줍니다. 여러분이 인터페이스 포인터의 복사본을 만들고, 원래의 포인터와 복사된 포인터를 함께 사용하려 할 때 이 메소드를 호출할 수 있습니다. 그러나 본 글에서 우리는 AddRef를 굳이 사용할 필요는 없습니다.
Release
COM 객체에게 레퍼런스 카운트를 감소할 것을 알려줍니다. 앞서 언급한 Release 호출 예제를 참고하시기 바랍니다.
QueryInterface
COM 객체에게 인터페이스 포인터를 요청합니다. 여러분은 coclass가 하나 이상의 인터페이스를 구현하고 있을 때 이 메소드를 사용할 수 있습니다.

우리는 이미 예제 코드에서 Release의 사용을 보았습니다. 그런데 QueryInterface는 무엇일까요? 여러분이 CoCreateInstance를 사용하여 COM 객체를 만들 때, 여러분은 인터페이스 포인터를 얻게 됩니다. COM 객체가 IUnknown을 제외하고 하나 이상의 인터페이스를 구현하고 있을 때, 여러분은 QueryInterface를 사용하여 여러분이 필요로 하는 추가적인 인터페이스 포인터를 얻을 수 있습니다. QueryInterface의 원형은 다음과 같습니다.

HRESULT IUnknown::QueryInterface(
    REFIID iid,
    void ** ppv);

파라미터의 의미는 다음과 같습니다.

iid
여러분이 요청하게 될 인터페이스에 대한 IID입니다.
ppv
인터페이스 포인터에 대한 포인터입니다. COM 객체가 iid 파라미터로 지정한 인터페이스를 구현하고 있다면, 그에 대한 인터페이스 포인터가 이 매개변수를 통해 반환됩니다.
앞서 언급한 쉘 바로가기 예제를 봅시다. 쉘 바로가기를 만들 수 있는 coclass는 IShellLinkIPersistFile을 구현하고 있습니다. 여러분이 이미 해당 COM 객체에 대해 IShellLink형의 인터페이스 포인터를 가지고 있다면, 같은 COM 객체에게 IPersistFile형의 인터페이스 포인터도 얻을 수 있습니다. 그 방법은 다음과 같습니다.
HRESULT hr;
IShellLink * pISL;
IPersistFile * pIPF;

hr = pISL->QueryInterface(IID_IPersistFile, (void **)&pIPF);

그 다음 QueryInterface가 정상적으로 작동하였는지 확인하기 위하여 SUCCEEDED 또는 FAILED 매크로를 사용하여 hr의 값을 검사합니다. 다른 형식의 인터페이스 포인터를 얻는데 성공하였다면, 여러분은 이 새로운 인터페이스 포인터도 사용할 수 있습니다. 단, 다른 인터페이스처럼 사용이 끝났을 때 여러분은 필히 pIPF->Release()를 호출하여야 합니다.

카테고리 “API/COM”
more...