본문 바로가기

Library/Windows Programming

WTL, Windows Template Library

MFC는 강력한 클래스 라이브러리이다. Win32 API로 Windows 프로그래밍을 하는 것은, Windows 프로그래밍을 배울 때가 아니라면 이 방법으로 실제로 일하는 것은 엄청난 시간이 걸리는 일이고, 그럼에도 불구하고 원하는 기능을 제대로 구현할 수 있을지 여부도 장담할 수 없다. 왜냐하면, MSDN에서 API에 대한 설명이 잘 되어 있다고 하더라도, 그 API를 처음부터 조합해서 원하는 기능을 만들어내는 것은 쉬운 일이 아니기 때문이다. API만 사용해서 ActiveX 컨트롤을 만든다고 생각해보라. 끔찍하지 않은가?

MFC는 사실 잘 구성되어 있는 클래스 라이브러리가 아니다. API를 래핑하는 구조에서 크게 벗어나지 못하고 있고, CObject에서 파생되어 나가는 구조라 가장 자주 쓰이는 CWnd과 같은 것은 상속에 상속을 받아서 엄청나게 많은 가상함수와 데이터멤버를 가진다. 그리고, 크기도 MFC 라이브러리가 링크되어야 하기 때문에 상당히 큰 덩치를 가지며, DLL 방식으로 링크하더라도 DLL의 크기는 최소 942KB의 크기를 가진다.

그럼에도 불구하고 MFC를 쓸 수 밖에 없는 이유는, MFC가 복잡하기는 해도 가장 풍부한 기능을 제공하며, MFC 외에는 다른 대안이 없기 때문이다. 현실적으로, Visual C++로 Windows 프로그래밍을 한다면 실전에서 MFC 외에 선택할 수 있는 대안은 없다. MFC가 C++의 표준이란게 없던 상황에서 만들어지다보니, 지금 관점으로 보면 그저 복잡하기만 한 자체 구현 방식이 구조를 복잡하게 만드는데 일조하고 있다. 물론, MFC 7.0 버전 이상은 과거의 그런 비표준 자체 구현 코드들이 표준으로 대체되고 있지만, 이 기능들은 하위 호환성 때문에 그냥 남아있는 상황이다. 가뜩이나 무거운 클래스 라이브러리인데 말이다.


.NET이 등장한 마당에, MFC와 SDK로 대표되는 C/C++ 프로그래머들이 선택할 수 있는 Windows 프로그래밍은 어떻게 될지 알 수 없다. 개인적으로는 MS에서 MFC를 대체할만한 라이브러리를 만들어주면 좋겠지만, 그것만 마냥 기다리고 있을 수는 없는 노릇이다. 무엇보다 .NET이란 근사한 물건이 있는 마당에, 굳이 과거 지향적인 방법으로 돌아갈지 의문이다. 물론, 지금도 Visual C++로 .NET 프로그래밍을 하는 것은 가능하다. 그러나, Visual C++로 .NET 프로그래밍을 하는 것은, Visual C++에 MS 자체 확장 기능이 너무 많아서 이게 진정한 C++ 프로그래밍을 하는 건지 알 수가 없다. 자체 확장 기능을 쓰면서 .NET 프로그래밍을 하다보면, 차라리 C#을 사용하는게 낫겠다는 생각이 들게 마련이다.

여튼, 이러한 불만을 가진 사람들이 그럭저럭 사용할만한 대안이 WTL이다. 사실, WTL은 ATL의 또 다른 파생물인데, ATL은 ActiveX 기능을 위해 새롭게 추가된 라이브러리이다. 여기에 UI를 처리할 수 있는, 소위 말해 '윈도우질'을 할 수 있도록 좀 더 구조를 다듬고 기능을 추가한 라이브러리이다. 하지만, WTL은 MS에서 공식적으로 지원하는 라이브러리가 아니다. WTL은 MS에서 오픈 소스로 공개했는데, 아마도 위에서 말한 이유 때문인 것 같다. 이런 개발자들의 불만을 무시할 수도 없고, 그렇다고 내부에서 공식적으로 추진하는 것도 시대 착오적 발상인 것 같고.. 그러다보니 이것을 그냥 오픈 소스로 공개해버린 것 같다.

WTL은 MFC보다 훨씬 단순하고, 잘 구현한 C++ 템플릿 클래스 라이브러리 같다. 메세지 전달을 효과적으로 처리하기 위한 MFC 메세지맵은 확실히 잘 구현한 기능이지만, 이것을 실제로 코드에서 구현하려고 보면 코드가 지저분해지는 느낌을 지울 수 없었다. WTL의 메세지맵은 MFC의 메세지맵과 비슷한 구조지만, 훨씬 단순하고 명료하게 처리한다. MFC의 CWnd에 해당하는 WTL에서의 개체는 CWindow인데, CWnd 클래스가 공룡같은 크기를 가진 것에 비해 CWindow 개체는 엄청나게 작고 깔끔하다. 무엇보다 CWindow는 interface - implementation 분리라는 원칙에 충실하게 설계되었으며, CWnd가 모든 기능을 자체적으로 구현하고 있는 것에 비해 CWindow는 CWindowImpl이란 실제 구현 클래스를 따로 가진다. 또, 메세지를 처리하기 위해 CWnd는 하나의 클래스에 계속 메세지 엔트리를 하나의 메세지맵에 추가하는데, CWindow는 '다중 상속'을 이용하여 메세지를 처리한다. CWindow 개체는 받은 메세지를 자신이 직접 처리할 것인지, 아니면 다중 상속을 통해 상속 받은 개체에게 그 처리를 넘길 것인지 선택할 수 있다. CWnd과 비교하면 더 작고, 분리된 디자인을 할 수 있다.

더 좋은 것은, MFC를 사용하려면 MFC 프레임워크에 의존해야 하지만, WTL은 그러한 프레임워크에 의존하지 않는다. 심지어, MFC 안에서 WTL을 섞어 쓸 수도 있다. MFC가 많은 기능을 제공하는 반대 급부로, 내부에서 무슨 일이 일어나는지 알기가 어려웠다면, WTL는 훨씬 단순하다. 또, 필요한 경우에만 인스턴스화되는 템플릿 코드의 특성상, 대단히 작고 빠른 코드를 생성하는 것이 가능하다.

WTL 8.0 버전은 Windows Vista를 위한 지원이 추가되었으며, Visual Studio 2005를 위한 프로젝트 템플릿도 지원하므로, 관심이 있는 사람은 한번 살펴보기 바란다. MFC의 그 복잡한 구조에 신물이 나지만 다른 대안이 없어서 고민하는 사람에게는 좋은 선택일 될 수 있을 것이다. (단정적으로 말하지 못하는 것은, 어디까지나 오픈 소스, MS에서 공식적으로 지원하는 것이 아니라서 언제 어떻게 될지 알 수 없기 때문에)

C++ 템플릿에 대해서 잘 이해하고 있고, ATL, 그리고 패턴에 대해서 어느 정도 이해하고 있다면 WTL은 사용하기에 그렇게 어렵지는 않을 것이다.