*이 내용은 개인 학습 내용을 정리한 것입니다.
1. 템플릿과 스마트 포인터
- 템플릿 : 여러 데이터 형에 대해 사용할 수 있는 하나의 함수 또는 클래스.
1) 함수 템플릿
- 실제 함수 생성이 아니라 함수를 정의하는 방법에 대해 기술. 실제로 해당 함수가 호출될 때, 함수가 포
함된다.
2) 클래스 템플릿
- 템플릿은 다양한 데이터 타입에 대해 동작하는 소스를 구현하는데 유용하다.
3) 스마트 포인터
예)
class CStudy{ public: CStudy(char *szStudy){ strcpy(m_szStury, szStudy); } ~CStudy(){ } virtual void Subject(){ ... } char m_szStudy[256]; };
class CStudyPointer : public CStudy{ public: CStudyPointer(char* szStudy) : CStudy(szStudy){ } };
template<class T> class CSmartStudy{ T* m_pT; public: CSmartStudy(T& rT){ m_pT = &rT; StudySetup(); } ~CSmartStudy(){ StudyCleanup(); } void StudyCleanup(){ ... } void StudySetup(){ ... } T* operator->() const { return m_pT; } };
void main(){ CStudyPointer studypt("COM"); CSmartStudy<CStudy> smartpointer(studypt); smartpointer->Subject(); } |
위와 같이 구현하면, 클라이언트가 pStudy를 항상 NULL로 설정하지 않아도 안전하게 접근가능.
COM에서도 스마트포인터를 추가해야 한다. -> QueryInterface()에서.
2. ActiveTemplateLibrary
- MFC대신 ATL을 사용할 경우 장점
1) MFC보다 개발 속도가 빠름
2) ATL은 C++의 템플릿을 기반으로 하기 때문에 MFC보다 코드가 간결함
3) ATL은 COM을 만들기 위한 최소한의 기능만 가지고 있어, 작게 설계되었고 부하가 적다
4) ATL은 NT4.0에서 지원되는 새로운 COM스레딩 모델을 지원
5) ATL3.0버전에 OLE DB Provider와 Consumer템플릿 클래스가 있어 DB접근이 쉬움
6) ATL은 UI보다는 업무로직을 구현하는데 있어 더 유리함
7) ATL은 가볍기 때문에 ActiveX를 만들 때, 유리.
- ATL사용시의 단점
1) 프레임워크를 지원하지 않아 UI개발이 어려움
2) UI를 포함하는 ActiveX개발에 있어 MFC보다 어려움
3) MFC에서 제공하는 클래스를 사용할 수 없음
3. 덧셈계산기 서버
- 프로젝트 생성시 프로젝트 유형의 옵션
i) Allow merging of proxy/stub code
마샬링 코드가 필요할 때, 선택. DLL옵션에만 가능.
*마샬링(Marshalling)
객체의 메모리 구조를 저장이나 전송을 위해, 적당한 자료형으로 변형하는것. 보통 다른PC나 다른 프로
그램간에 데이터가 이동되어야할 때 사용된다. 복잡한 통신을 단순화 하기 위해 기본요소대신 통신을 위
한 맞춤형 오브젝트를 사용. 반대개념은 언마샬링
cf) 직렬화
객체를 나중에 복원할 수 있는 byte stream으로 변환하는 것.
ii) SupportMFC
MFC라이브러리를 사용할 때 체크. 체크가 안되어있으면 MFC클래스 사용을 못함. 그러나 무작정 체크하
면 MFC로 COM을 만드는 경우보다 더 부하가 많이 걸리는 COM을 만들수도 있다.
iii) Support MTS
Microsoft Transaction Server를 지원하려고 할때 선택
- MFC와 ATL의 다른점.
MFC는 인터페이스를 직접 디자인 하지만 ATL은 위저드를 통해서 만들 수 있다.
4. 덧셈계산기 클라이언트
- 클라이언트에서 만들은 인터페이스 호출하기.
DLL서버에서 제작했던 TLB파일을 import하면, ATL 위저드가 그에 맞는 스마트 포인터를 만들어 준다.
5. ATL다시보기
- ATL COM은 CWinApp로부터 파생되지 않고, _ATL_MODULE이라는 구조체로 파생됨.
_ATL_MODULE로부터 CComModule이 정의되고, 이CComModule이 CWinApp역할을 수행.
1) CComModule
CComModule클래스는 COM서버 모듈을 구현. 클라이언트에서 COM객체에 접근할 수 있게 함.
이 클래스는 _ATL_MODULE로부터 파생된다.
*_ATL_MODULE구조체
struct _ATL_MODULE{ //Attributes public: UINT cbSize; HINSTANCE m_hInst; HINSTANCE m_hInstResource; HINSTANCE m_hInstTypeLib; _ATL_OBJMAP_ENTRY* m_pObjMap; LONG m_nLockCnt; HANDLE m_hHeap; union{ CRITICAL_SECTION m_csTypeInfoHolder; CRITICAL_SECTION m_csStaticDataInit; }; CRITICAL_SECTION m_csWindowCreate; CRITICAL_SECTION m_csObjMap; DWORD dwAtlBuildVer; _AtlCreateWndData* m_pCreateWndList; bool m_bDestroyHeap; GUID* pguidVer; DWORD m_dwHeaps; HANDLE* m_phHeaps; int m_nHeap; _ATL_TERMFUNC_ELEM* m_pTermFuncs; }; |
- CComModule은 ATL을 레지스트리에 등록하고, 인스턴스를 생성하는 역할을 한다.
- 객체 맵은 BEGIN_OBJECT_MAP()으로 시작해서 END_OBJECT_MAP()매크로로 끝난다.
BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_ISimpleCalc, CSimpleCalc) END_OBJECT_MAP() |
- 객체 맵은 _ATL_OBJECT_ENTRY 구조체 배열로 구현되며, 다음과 같은 정보를 포함
i) 시스템 레지스트리에 COM객체 등록 및 해제
ii) 클래스팩토리 COM객체 생성 방법
iii) COM객체 생성 방법
2) CComModule객체의 구현
- ATL COM은 CComObjectRootEx, CComCoClasss, IDispatchImpl로부터 파생된다.
a) CComObjectRootEx
ATL COM객체의 IUnknown인터페이스의 내부 구현 코드를 제공하는 역할. 또한, 스레딩 모델을 선언하
여 준다. CComSingleThreadModel을 통해 구현됨.
b) CComCoClass
COM개체의 클래스는 COM개체의 디폴트 클래스 팩토리, 통합, CreateInstance와 같은 함수를 제공하는 COM객체를 정의한다.DECLARE_CLASSFACTORY() 매크로를 이용해 생성하는 템플릿
c) IDispatchImple
IDispatchImpl은 IDispat부분에 관한 구현 부분을 제공.
d) 클래스 내부의 구현 - BEGIN_COM_MAP
COM객체 클래스는 BEGIN_COM_MAP과 END_COM_MAP매크로로 구현되는 COM맵이 정의됨
BEGIN_COM_MAP(CSimpleSum) COM_INTERFACE_ENTRY(ISimpleSum) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() |
6. 스마트포인터
- ATL에서 매우 중요한 개념이다. 코드를 깔끔하게 정리해 줌
1) _com_ptr_t
- 형식라이브러리 (TLB)는 COM객체의 인터페이스들에 대해 _com_ptr_t 템플릿을 사용하여 스마트포인
터 클래스를 정의한 후 이를 클라이언트에게 제공
- 스마트포인터객체는 COM객체의 생성 기능을 가지고 있다.
2) CComPtr과 CComQIPtr
- CComPtr, CComQIPtr : ATL에서 VC++의 _com_ptr_t 스마트포인터 템플릿클래스에 해당되는 클래스
template <class T> class CComPtr template <class T, const IID* piid> class CComQIPtr |
위 두 클래스는 인터페이스에 대해 자동적으로 AddRef와 Release를 호출해 준다. 표준 COM인터페이
스를 포장한 객체 래퍼다.
- CComPtr : 템플릿 선언시 넣어준 타입에 맞는 인터페이스를 래핑
CComQIPtr : 인터페이스 포인터를 관리는 하지만, 객체 생성과 할당시 QueryInterface()를 수행.
IUnknown인터페이스를 수용하지 않음
7. ATL로 할수있는 일들
ATL Object Wizard는 다음과 같은 다양한 종류의 기능을 포함하는 COM객체를 생성해 줌
1) Object카테고리
객체명 |
설명 |
Simple Object |
이중인터페이스를 지원하는 자동화 객체 |
Add-in Object |
MS Dev Studio의 IApplication인터페이스 조작을 위한 add-in객체. |
Internet Explorer Object |
MSIE의 사이트에 대한 포인터를 조작하기 위한 객체. 직접 IE제어 가능 |
ActiveX Server Component |
액티브 서버 페이지가 제공하는 인터페이스 사용할 수 있는 기능제공 |
MS Transaction Server |
다중 사용자용 서버 컴포넌트를 개발할 수 있도록 지원. MTS필요 |
Component Register Object |
모듈내의 모든 CLSID를 등록하는 것을 지원. |
MMC SnapIn |
MS Management Console 스냅-인 구현시 사용함 |
2) Controls 카테고리
컨트롤 명 |
설명 |
Full Control |
모든 ActiveX컨테이너(VC, VB, IE등)에서 사용가능한 컨트롤 |
Lite Control |
MSIE에서만 사용가능한 인터페이스를 지원하는 컨트롤 |
Composite Control |
다른 컨트롤을 포함하는 복합 컨트롤. 모든 컨테이너 사용가능 |
HTML Control |
동적html기능을 가진 컨트롤 제작 가능. 모든 컨테이너 사용가능 |
Property Page |
속성페이지를 제작할 수 있는 컨트롤 |
Lite Composite Control |
Composite Control과 같지만 MSIE에서만 동작 가능하다 |
Lite HTML Control |
HTML컨트롤과 같지만 MSIE에서만 동작 가능 |
8. 새로운 클래스의 생성
1) New Class 대화상자의 사용
ATL Object Wizard는 기본적으로 하나의 인터페이스만 노출하도록 제한한다. 기 생성된 COM객체에 다른 인터페이스를 추가하려면 아래와 같이 할것
i) IDL파일에 인터페이스를 정의한다.
ii) COM개체 클래스가 해당 인터페이스에서 파생하도록 기초 클래스를 추가한다
iii) COM_INTERFACE_ENTRY 매크로를 사용하여 COM맵에 인터페이스를 추가
iv) 해당 인터페이스의 메소드 함수 원형을 추가한다.
출처 - COM Bible
댓글