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

Chapter 01. 왜 COM인가?

by 곰네Zip 2014. 10. 29.

*이 내용은 개인 학습 내용을 정리하는 것이 목적입니다.

 

1.1 COM의 등장

  1.1.1 메인프레임 시대

    - 메인프레임에서 모든 작업을 처리. 프로그램의 크기가 커서 유지보수가 어려운 단점.

 

  1.1.2 클라이언트 / 서버 시대

    - 메인프레임 방식으로는 비싼 유지보수비용, 업무요구에 대한 신속한 대처등 문제가 있음.

     -> 업무를 작은규모의 서버들에게 분할하여 처리. 이 시기엔 데스크탑의 성능도 향상되어 클라이언트에

       서 데이터를 적절히 가공하는 일도 하게 됨.

 

  1.1.3 3계층 클라이언트 / 서버 시대

    - 클라이언트-서버 관계를 클라이언트-별도어플리케이션서버-데이터베이스서버 3개로 분할.

 

  1.1.4 컴포넌트기반 분산 객체 기술의 등장

    - 분산 클라이언트/서버에서는 어플리케이션의 유기적인 통합과 커뮤니케이션이 필요함

     -> 컴포넌트 기반 분산 객체 기술이 등장

    1) 컴포넌트 소프트웨어의 조건

      - 언어독립적이어야 한다.

          언어별로 다른 메모리 사용과 커뮤니케이션 방식을 가짐. -> 표준이 필요함

      - 위치투명성을 제공해야 한다

          위치에 관계없이 컴포넌트를 사용할 수 있어야 한다.

      - 버전관리가 쉬워야 함

      - 특정업체에 종속적이지 않아야 함

 

    2) ORB (Object Request Broker)

      - 객체에 대한 서비스 요청을 중계하는 중계자.

        -> 클라이언트는 ORB를 통해 서비스 요청을 하므로 서버 컴포넌트가 어디있는지 알 필요 없다. 이것

           은 위치 투명성의 특징을 가질 수 있도록 함.

 

    3) 인터페이스 정의 언어 (IDL, Interface Definition Language)

      - 서로 다른 객체끼리 통신을 위해서는 인터페이스가 필요. 이러한 인터페이스 정의를 위해 IDL이 필요.

 

  1.1.5 COM의 역사

    1) COM/DCOM은 OLE에서 부터 시작.

      - OLE : Object Linking and Embedded. 객체를 연결하고 포함하는 기술. 초기 OLE는 DDE(Dynamic

       Data Exchange)를 기반 기술로 하였으나 단점이 많아 OLE 2.0부터는 COM으로 대체됨.

        -> OLE자동화와 OLE컨트롤(VBX를 대체)이 추가되었다.

      - OLE자동화와 OLE컨트롤 : VB같은 매크로 레벨 언어에서 COM의 인터페이스에 접근이 어려움

        -> VB에서 디스패치 인터페이스를 정의하여 COM컴포넌트를 VB에서 사용하기 위해서는 디스패치

           인터페이스의 속성과 메소드를 통해 서비스를 제공하도록 함.

      - 자동화서버, 자동화 컴포넌트 : OLE의 자동화 서비스를 제공하는 쪽

        자동화클라이언트, 자동화 컨트롤러 : OLE의 자동화 서비스를 사용하는 쪽

      - 자동화 기술은 매크로나 스크립트 언어에서는 유리하나, C++처럼 인터페이스에 직접 접근 가능한 언

        어에서는 유리하지 않음.(속도의 문제). -> 이중 인터페이스로 해결 (자동화, 직접접근)

      - 리모트OLE자동화로 3계층 클라이언트/서버를 시작하였으나, DCOM에서 본격적으로 시작됨

      - 트랜잭션처리나 컴포넌트관리등은 DCOM만으로는 어려워 이런 서비스를 제공하기 위해 MTS가 생김

        -> MTS가 윈도우 OS와 통합되어 COM+

 

1.2 COM컴포넌트 인터페이스

  1.2.1 인터페이스 정의

     - 다른 언어로 구현된 클라이언트/서버간에 커뮤니케이션을 위해서 interface를 사용한다.

        -> interface : 컴포넌트가 자신의 서비스를 클라이언트에 노출하는 방법

     - 모든 COM 컴포넌트는 하나의 IUnknown 인터페이스를 필수적으로 제공해야 함.

 

  1.2.2 인터페이스 메모리 구조  

     - 인터페이스의 메모리 구조

             

 

 

 

 인터페이스 함수테이블

또는 가상함수테이블

 

 컴포넌트의 인터페이스

 함수 구현

 

 ------>

 vptr

 ----->

 queryInterface함수포인터

 ---->

 HRESULT QueryInterface(){...}

 

 interface

포인터

 데이터

 

 AddRef 함수 포인터

 ---->

 ULONG AddRef(){...}

 

 

 Release 함수 포인터

 ---->

 ULONG Release(){...}

 

 

 

 

 Method1 함수 포인터

 ---->

 HRESULT Method1(){...}

 

 

 

 

 Method2 함수 포인터

 ---->

 HRESULT Method2(){...}

 

 

 

 

 Method3 함수 포인터

 ---->

 HRESULT Method3(){...}

 
             

        COM인터페이스의 메모리 구조는 C++컴파일러가 추상적인 클래스에 대해 생성한 메모리 구조와 일치

 

  1.2.3 인터페이스 구현과 상속

     - COM은 다형성은 지원하지만 상속성은 지원하지 않는다.

       -> 상속성에는 인터페이스 상속과 구현 상속이 있다.

      * 인터페이스 상속 : 순수 가상함수의 상속

        구현 상속 : 가상함수와 비가상함수의 상속을 말함

      * 순수가상함수 : 가상함수이나, 함수의 정의부분 없이 선언만 있음

        가상함수 : 파생클래스에서 가상함수를 받는 함수가 없다면, 기본 클래스 함수가 호출되고, 있을 경우

                      파생클래스의 가상함수를 호출시켜주는 매체가 되는 함수

        비가상함수 : 일반멤버 함수

        (출처 : http://girtowin.tistory.com/30)

 

    - 구현상속은 크게 두가지 단점이 있다.

      i) 언어종속적이다 (COM에서 사용하기 어렵다)

      ii) 기초클래스가 손상되기 쉬움.

       예 )

 class Base{

 public:

      virtual void Func1(){ cout << "func1" << endl; }

      virtual void Func2(){ cout << "func2" << endl; }

      virtual void Func3(){ cout << "func3" << endl; Func2(); }

 };

 

 class Child{

 public:

      void Func1(){ cout << "child1" << endl; }

      void Func2(){ cout << "child2" << endl; }

 };

 

 //main

 Child c1;

 c1.Func1();

 c1.Func2();

 c1.Func3();

       위와 같이 호출하면, 결과는 다음과 같다.  

 child1

 child2

 func3

 child2

       Func3에서는 Base의 Func2를 호출하려 하였으나, 실제로는 Child의 Func2가 호출된다. Base클래스

     의 기능이 달라진다.

    - 위와 같은 이유로, COM에서는 인터페이스 상속을 사용한다.

 

 

1.3 COM컴포넌트와 GUID

  1.3.1 COM컴포넌트의 종류

     1) 실행 위치에 따른 분류

       - In-process Server

         클라이언트와 같은 프로세스에서 실행됨. DLL로 구현됨

       - Out-process Server

         클라이언트와 다른 프로세스에서 실행됨. EXE로 구현됨

     2) Out-process Server는 다시 두 분류로 나눌 수 있음

       - local server

         서버가 클라이언트와 같은 시스템에서 동작

       - remote server

         서버가 클라이언트와 다른 시스템에서 동작

 

  1.3.2 GUID

     1) interface이름만으로 해당 인터페이스의 고유성을 나타내기 어려움

       - 중복되지 않을 고유 번호가 필요하고 이것이 GUID. 128비트의 구조체

 

출처 - CBD, Component Development with Visual C++,ATL

반응형

댓글