7.1 ATL의 특징
- COM컴포넌트를 빠르게 구현할 수 있도록, IUnknown, IClassFactory등의 인터페이스에 대한 코드가 구현되어 있음
7.1.1 ATL의 장점
- 작고 빠르고 확장성을 갖는 COM컴포넌트를 만들어 줌.
- 템플릿은 코드에서 사용하여 타입이 명확할 때, 컴파일러가 코드를 만들어 준다. 즉, 사용안되는 경우 해당 템플릿은 코드에 포함되지 않는다. 그리고 ATL에서는 IUnknown등의 구현이 지원되어 편리하다.
7.1.2 ~ 7.1.3 ATL프로젝트 만들기, ATL COM객체 추가
- Visual Studio에서 ATL프로젝트를 만들면 '$(프로젝트명)PS'의 프로젝트가 하나 추가되어있다. 이는, 프록시/스텁을 VS에서 만들어주었다. 또한 DllRegister/Unregister등의 함수도 ATL에서 구현해준다.
- 프로젝트->클래스 추가 -> ATL단순개체로 추가를 해 주면, 기본적인 코드는 역시 VS에서 생성해준다.
7.1.4 ATL COM객체 구현
- VS의 프로젝트 목록에서 원하는 인터페이스에 '메소드 추가'를 이용하여 마법사로 생성하면, 기본 코드는 VS가 알아서 추가해 준다. (idl, 헤더등) 추가된 함수의 내부만 구현하면 된다.
7.2 ATL기반클래스
7.2.1 ATL모듈 클래스
- ATL프로젝트마법사를 이용하여 프로젝트 생성시 dllmain.h (VS2010기준)에 다음과 같은 코드를 볼 수 있다.
class CHelloServerModule : public ATL::CAtlDllModuleT< CHelloServerModule > { ... }; |
> 위 CAtlDllModuleT클래스에서 앞에서 추가해주었던 DllRegisterServer, DllUnregisterServer, GetClassObject, DllCanUnloadNow등의 함수를 구현해 준다.
7.2.2 ATL COM객체 기초 클래스
- 앞에서 ATL단순개체 추가를 통해 클래스를 생성하면 다음과 같이 생성된다.
class ATL_NO_VTABLE CHello : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CHello, &CLSID_Hello>, public IDispatchImpl<IHello, &IID_IHello, &LIBID_HelloServerLib, /*wMajor =*/ 1, /*wMinor =*/ 0> { ... } |
- CComObjectRootEx 템플릿클래스에서는 IUnknown인터페이스 내부 구현을, CComCoClass템플릿에서는 디폴트클래스팩토리 COM객체를 정의해 준다. CComColass에서 AddRef, Release, QueryInterface에 대해 구현을 해줌
- COM객체클래스는 BEGIN_COM_MAP ~ END_COM_MAP에 정의된 COM맵을 사용하여 인터페이스를 관리함.
1) 사용자 COM객체 생성과정
- CocreateInstance -> DllGetClassObject호출됨. 여기에서 AtlComModuleGetClassObject를 호출하는데, 여기에서 _ATL_OBJMAP_ENTRY구조체 배열에서 요청된 COM객체를 찾는다.
2) ATL_NO_VTABLE매크로
- _ATL_DISABLE_NO_VTABLE이 정의되어 있지 않다면, 이 매크로는 __declspec(novtable)로 확장된다. 이 정의를 통해 컴파일러가 이 클래스의 가상함수 테이블에 대해 무시함으로써, 속도와 메모리사용에 향상을 가져온다. 이는 ATL에 기본으로 정의되어있다. 단, 이 경우 클래스의 생성자에서 가상함수를 호출하지 않도록 주의. (초기화 되지 않은 영역이면 문제가 된다.)
* ATL마법사를 사용하여 진행시, wchar_t타입을 인자로 주었을 때, ushort타입과 wchar_t와 호환이 안된다고 나온다. 이때, idl파일에서 [in] wchar_t*를 [in,string]wchar_t*로 변경하여 주자.
* 그리고 클라이언트에서 해당 ATL COM을 사용하려면, 클라이언트App.cpp 파일에서 InitInstance함수 내에 AfxOleInit()을 수행해 줄 것. (해주지 않으면 종료시에 AV를 확인할 수 있음)
* CreateInstance에서 찾을 ID는 CLSID에 등록한 이름으로 넘겨주면 찾아준다.
7.3 스마트 포인터 클래스와 데이터타입 클래스
- VC++에 _com_ptr_t가 있으면, ATL에는 CComPtr과 CComQIPtr이 있다. 이들은 스마트포인터임. 인터페이스에 대해 자동으 AddRef,Release를 호출하여 레퍼런스 카운터를 관리해준다. 그러나 _com_ptr_t와 다르게 COM객체의 인스턴스를 생성하지는 못한다. CComQIPtr은 QueryInterface까지 지원함
7.4 attribute기반 프로그래밍
- ATL마법사를 이용해서 특성을 주며 컴포넌트의 개발이 가능하지만, 직접 입력하여 특성을 주는 것도 가능하다. 컴포넌트를 코드로만 구현하기 위해서는 다음 링크(MSDN)의 COM관련 특성 부분을 찾아보면 된다.
http://msdn.microsoft.com/ko-kr/library/f520z3b3.aspx
댓글