본문 바로가기
Programming/Tips(C++,C#)

Chapter 07. ATL개요

by 곰네Zip 2014. 11. 10.

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

반응형

댓글