블로그 이미지
Kanais
Researcher & Developer 퍼즐을 완성하려면 퍼즐 조각들을 하나 둘씩 맞춰나가야 한다. 인생의 퍼즐 조각들을 하나 둘씩 맞춰나가다 보면 인생이란 퍼즐도 완성되는 날이 오려나...?

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Notice

2015. 5. 11. 16:05 Programming/COM

이글은 '선문비트 고급과정'에서 강의받은 내용을 토대로 작성하였으며, 비트 교육센터 자료를 참고하여 올린내용입니다. 문제가 될시 삭제가 될 수 있습니다.


사용툴 : Visual Studio 2008

작성날짜    : 2011-03-17



MFC로 프로그래밍 할 때의 단점

무겁다.

 

ATL 개요

순수한 C++ 언어를 사용한 COM 프로그래밍

 

많은 코드 작업 요구

반복적 작업이 많음

에러가 발생하기 쉬움(작성하는 코드들이 많아 지다 보니..)

Microsoft Visual C++ 의 ATL (Active Template Library)

템플릿에 기반을 둔 클래스 라이브러리

작고, 빠르고, 확장성을 갖는 COM 개체를 손쉽게 구현할 수 있다.

(마우스 클릭만으로 만들 수 있다. - 함수 껍데기 등을 만들어준다)

- But, MFC 프로그래밍과는 달리 COM 의 내부구조에 대한 이해가 필요하다.

 

MFC 6.0 & ATL 3.0

Visual c++ 6.0 부터 2005까지 업데이트가 되지 않았다가, 2008때 대대적인 업데이트를 했다.

 

- ATL (Active Template Library) : C++ 템플릿(template)을 사용하여 작성된 클래스 라이브러리

- IUnknown, IClassFactory 등의 인터페이스에 대한 구현 코드제공

- Visual C++ 6.0 MFC 6.0 과 ATL 3.0

- MFC&T

- OLE DB 에서의 Provider 와 Consumer 템플릿 클래스가 추가됨

- MFC 와 ATL 비교

MFC 라이브러리

ATL

프레임워크를 통한 풍부한 사용자 인터페이스 제공

프레임워크 지원 없음 – 빈약한 사용자 인터페이스

덩치가 큼, 느림

작고 빠름, 인터넷용 ActiveX 컨트롤 수현에 적합

 

 

덧셈 연산 서버

Step 1. 새 프로젝트 탭에서 ATL -> ATL 프로젝트를 선택 후 프로젝트 이름 입력.

 

 

Step 2. 마침 버튼을 눌러 프로젝트를 생성한다.

 


* Allow merging of proxy/stub code

마샬링 코드가 필요하다면 이 체크 박스를 선택한다. 이 옵션은 DLL 버전의 경우에만 선택할 수 있으며, 나머지는 선택할 수 없다. 마샬링 코드는 프록시와 스텁을 구현하기 위해 필요한 코드이다.

* Support MFC

- MFC에서 지원되는 클래스가 필요하다면 이 체크 박스를 선택한다. 이 옵션의 사용은 MFC로 COM을 만드는 경우보다 더 부하가 많이 걸리는 결과를 초래할 수 있다.

* Support MTS

- Microsoft Transaction Server를 지원하고자 할 때 이 체크 박스를 선택한다.

 

프로젝트를 Build 하면 MIDL 컴파일러가 다음의 파일들을 새롭게 생성한다.

파  일

설  명

SumSrv.h

Interface 정의 부분이 추가된다.

SumSrv.tlb

Client는 이 파일을 참조하여 Server에 접근한다.

SumSrv_i.c

IDL 파일을 참조하여, MIDL 컴파일러가 생성시킨 Interface 수현 부분이다.

SumSrv.rgs

Interface를 Registry에 등록하기 위해 등록정보가 포함된 파일이다.

 

COM 객체 유형 선택

Step 3. 솔루션 탐색기의 노드를 마우스 우클릭 -> 추가 -> 클래스 선택

 

 

클래스 추가 창이 뜨면  ATL 단순 개체를 선택 후 추가 버튼 클릭

 

 

등록 정보 설정

Step 4. 약식 이름 텍스트 상자에 COM 객체명을 입력한다. 이때 입력된 COM 객체명을 기반으로 COM 객체 클래스 명과 소스 및 헤더 파일명, 인터페이스명, ProgID등이 자동으로 결정된다. 필요에 따라 수정이 가능하다. 등록정보는 .idl 파일에 추가로 자동 등록된다.

 

 

스레딩 모델과 인터페이스, 집합체 등의 옵션을 선택한다.

스레딩 모델의 경우 인프로세스 서버이므로 “아파트”모델을 선택하자.

  

 

 

메소드 추가

Step 5. ATL에서는 MFC와 같이, 메소드를 추가 하기 위해 ClassWizard를 사용할 수 없다. 왜냐하면, ATL은 템플릿에 기반을 둔 라이브러리이기 때문에 클래스의 등록 정보 파일은 만들지 않는다.


클라이언트 입장에서 pSum을 구하기 위해 m_object -> sum(x,y,&pSum)으로 해야한다. pSum = (int) m_object -> sum(x,y)방식으로 하고자 한다면 parameter의 인자를 
[in] int x, [in] int y, [out,retval] int* pSum 으로 IDL을 편집한다. VisualBasic 혹은 ASP에서는 포인터 개념이 없기 때문에, 함수의 리턴 값으로 그 결과를 구해야 한다.

 


함수의 구현

Step 6. Sum 메소드를 추가하게 되면, IDL 파일의 인터페이스 선언부와 COM클래스의 헤더파일에 Sum 메소드가 자동으로 추가된다. 또한, 클래스 구현 파일에도 개발자가 코드만을 추가하도록 구현 함수가 자동 추가된다.

STDMETHODIMP CSimpleSum::Sum(int x, int y, int * pSum)

{

        // TODO: 여기에구현코드를추가합니다.

        *pSum = x + y;

        return S_OK;

}

 

SumSrv 파일의 빌드

Step 7. 프로젝트를 빌드하면 인터페이스를 등록하기 위해서 레지스트리 등록정보 파일이 생성된다.

HKCR

{

        SumSrv2.SimpleSum.1 = s 'SimpleSum Class'

        {

               CLSID = s '{6DA6D66D-E715-442D-9B62-CE09C24C1D9A}'

        }

        SumSrv2.SimpleSum = s 'SimpleSum Class'

        {

               CLSID = s '{6DA6D66D-E715-442D-9B62-CE09C24C1D9A}'

               CurVer = s 'SumSrv2.SimpleSum.1'

        }

 

HKCR는 HKEY_CLASSES_ROOT, 코드값 앞의 s는 문자열을 의미한다.

 

SumSrv.rgs 파일

NoRemove CLSID

{

        ForceRemove {6DA6D66D-E715-442D-9B62-CE09C24C1D9A} = s 'SimpleSum Class'

        {

               ProgID = s 'SumSrv2.SimpleSum.1'

               VersionIndependentProgID = s 'SumSrv2.SimpleSum'

               ForceRemove 'Programmable'

               InprocServer32 = s '%MODULE%'

               {

                       val ThreadingModel = s 'Apartment'

               }

               'TypeLib' = s '{A3324726-206D-46AB-B5EB-AF5E108264F7}'

        }

}

- NoRemove : 레지스트리의 서브키를 삭제 하지 않는다.

- ForceRemove : 레지스트리에 등록하기전에 관련 서브키를 강제로 삭제한다.

- %MODULE% 매크로는 컴포넌트의 실행 파일이나 DLL의 절대 경로명을 나타내며, val 속성이 앞에 붙으면 해당 항목이 키 값임을 나타낸다.

 

덧셈 서버 클라이언트

Step 1. 새프로젝트에서 Project name은 “SumClient”로 하고, 다이얼로그 베이스 윈도우로 만든다. 

 

리소스 추가하기

Step 2. 리소스 다이얼로그에서 적당한 폼으로 편집하고, 컨트롤 속성을 부여한다.

 

OLE 초기화

Step 3. CWinApp::InitInstance() 함수 구현부에서 다음과 같이 OLE 초기화를 시켜 준다.

BOOL CSumClientApp::InitInstance()

{

        AfxOleInit();

AfxEnableControlContainer();

 

SimpleSum Interface 호출

Step 4. SumSrv Server 내의 SimpleSum Interface를 초기화 하기 위해서 헤더파일에 Server의 타입 라이브러리 파일인 SumSrv.tlb 파일을 Import 시킨다.

또한, ISimpleSumPtr의 스마트 포인터 객체를 선언한다.

// CClientDlg 대화상자

#import "../SumSrv/SumSrv.tlb" no_namespace

 

class CSumClientDlg : public CDialog

{

// 생성입니다.

public:

        CSumClientDlg(CWnd* pParent = NULL);  // 표준생성자입니다.

중략 -

// 구현입니다.

protected:

        HICON m_hIcon;

        ISimpleSumPtr m_Simplesum;

 

Step 5. SumSrv 내의 SimpleSum의 인스턴스를 생성시켜 Sum메소드까지 접근할 수 있도록 다이얼로그의 OnSum() 함수를 구현하자.

void CClientDlg::OnSum()

{

        int x, y, pSum;

 

        x = GetDlgItemInt(IDE_XVALUE);

        y = GetDlgItemInt(IDE_YVALUE);

 

        HRESULT hr = m_SimpleSum.CreateInstance("SumSrv.SimpleSum");

        if(SUCCEEDED(hr))

        {

               m_SimpleSum->Sum(x, y, &pSum);

               SetDlgItemInt(IDC_RESULT, pSum);

        }

}

 

'Programming > COM' 카테고리의 다른 글

[COM] ATL ActiveX  (0) 2015.05.11
[COM] ActiveX Control(Graph)  (0) 2015.05.11
[COM] IDL  (0) 2015.05.11
[COM] IUnknown  (0) 2015.05.11
[COM] COM 이란?  (0) 2015.05.11
posted by Kanais