*이 포스팅은 개인 학습을 위해 내용을 정리한 것이 목적입니다.
1. COM의 개요
과거 소프트웨어 개발의 문제점 중 하나가 유지보수. 이를 해결하기 위해 프로그램의 모듈화가 대두됨. 유지보수 문제 외에도 다음과 같은 문제가 있음.
i) 단일 소프트웨어에서의 크기 증가시, 개발/유지/보수가 어렵다는 문제가 있음. 그에 따라 DLL이 사용되었다. 그러나 DLL을 공유하는 소프트웨어의 경우 DLL버전이 다를 경우 프로그램 수행에 치명적인 문제가 발생한다.
ii) 같은 C++로 구현하여도 다른 회사의 컴파일러에서는 호환되지 않음. (이진 표준의 부재)
iii) 소프트웨어의 경우 하드웨어처럼 유연성을 가지고 있지 못함
iv) 윈도우용 소프트웨어는 윈도우에서만 사용가능. 그러나 사용자는 모든 플랫폼에서 실행되는 소프트웨어를 원한다.
DLL을 사용할 경우, DLL의 이름이 중요하다. (이름이 변경되면 로딩을 못하므로) 그러나 여러 개발팀에서 개발 시, DLL이름의 충돌이 우려된다. 이를 해결하기 위한 방법이 COM이다. COM의 장점은 다음과 같음
i) 이식성이 강함.
ii) 컴포넌트로 개발할 경우 하드웨어처럼 유연성을 제공함. 소프트웨어 업그레이드시, 전체 업그레이드가 아닌 해당 컴포넌트만 복사하면 됨
iii) 여러 프로젝트에 동일한 코드가 존재하면, LIB이나 DLL로의 제공이 최상의 선택이었으나, 이 경우 버전이 올라가면 재컴파일이 필요하다. 그러나 COM의 경우 재컴파일을 해야할 필요가 없음
iv) 컴포넌트 단위의 개발을 가능하게 만들어, 소프트웨어의 모듈화를 제공하였음
v) 플랫폼에 대해 독립적. (이진 표준을 준수하는 플랫폼에서 사용가능)
COM은 응용프로그램에서 접근 시, 이름이 아닌 GUID를 이용하여 접근한다. (이름 충돌 가능성 제거됨)
2. C++과 DLL의 차이점
1) C++로 구현한 가산 프로그램
다음과 같은 단순한 예제 프로그램을 가정하자.
#include <iostream>
class CSimpleCalc { int x; int y; public: CSimpleCalc(int x1, y1){ x= x1; y= y1; } int sum(){ return x+y; } }
void main() { int x1 = 3; int y1 = 4; CSimpleCalc obj(x1,y1); cout << "x + y = " << obj.sum() << endl; } |
위 프로그램에서 sum의 내부가 변경되어야 한다면, 프로그램을 재컴파일 하여야 한다. 만약 코드가 커질 경우 재컴파일에는 많은 시간이 소요된다.
해결책 중 하나는, 위 프로그램을 main프로그램 A와 CSimpleCalc로 구성된 B로 나누는 것이다. 이럴 경우 컴파일은 B에 대해서만 다시 컴파일 하고, 재배포 되면 된다. 프로그램A에서는 재컴파일 과정 없이 B를 불러올 수 있다. 이러한 방법을 동적바인딩이라고 하며, 프로그램B를 DLL로 구성하면 됨.
2) DLL을 이용한 가산 프로그램.
언어에 독립적인 DLL을 개발하기 위해서는 일반DLL을 이용해야 함. 아래는 위 프로그램 중 CSimpleCalc를 DLL로 구현한 예제.
#include <iostream> #include <objbase.h> BOOL WINAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved){ switch(dwReason){ case DLL_PROCESS_ATTACH: break; } return TRUE; } STDAPI_ (int) sum(int x, int y){ return x+y; } |
클래스를 사용할 수 없어서, 함수의 원형이 변경되었지만 응용프로그램과 DLL로 분리되어있다.
DLL 호출에는 정적바인딩과 동적바인딩 두 방법이 있다. 정적바인딩의 경우 컴파일시간에 결정이 되기에
DLL의 변동시 재컴파일/재배포를 해야한다. 동적바인딩은 실행시간에 결정되어 이런제약은 없음.
동적연결을 이용하여 DLL을 호출하기 위해서는 regsvr32를 이용하여 해당 DLL을 등록/해제 해주어야함.
* DLL을 로드하고, 사용하고, 해제하는 3가지의 메소드
i) LoadLibrary
HINSTANCE LoadLibrary(LPCSTR lpLibFileName) |
DLL을 불러오는 함수. 리턴되는 해당 모듈의 핸들을 가지고 GetProcAddress로 DLL내의 함수에 접근.
해당 DLL의 위치를 찾는 순서는 'Windows -> Root -> Path' 순으로 찾음.(경로 없을 경우)
ii) GetProcAddress
FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName) |
hModule은 i)에서 가져온 모듈의 핸들, lpProcName은 export된 함수 이름. 성공시 함수의 주소가 리턴
된다. (캐스팅 해주어야 함). 찾지 못하면 NULL리턴.
iii) FreeLibrary
BOOL FreeLibrary(HMODULE hModule) |
라이브러리를 더이상 사용하지 않을 때, FreeLibrary를 이용하여 라이브러리를 언로드 함. 성공시 TRUE,
실패시 FALSE리턴.
위 DLL의 방법은 프로그램의 모듈화를 이루었다. 하지만 객체지향적이지는 못하다. 캡슐화와 다형성에서
어느정도 달성 하였으나, 상속에 있어서는 아님.
DLL의 경우 B라는 DLL이 A라는 DLL로부터 상속을 받을 수는 없다.
하지만, COM의 경우 DLL을 이용하여 함수가 아닌 클래스 자체를 메모리에 로딩할 수 있다. 따라서, 이미
만들어진 클래스를 이용하여 프로그램 제작이 가능하다.
3. Component Object Model
COM : 컴포넌트를 만들기 위한 규정을 정리해 놓은 규정집
1) Component
사전적 정의 : 어떤 제품의 부품이나 구성요소. 각각의 특정한 기능을 수행하면서 다른 컴퓨터에서도 사용이 가능하고, 하나의 제품이 될 수 있다.
*모듈화와의 차이점
- 모듈화 : 프로그램의 분리를 통한 개발 기간의 단축
- 컴포넌트 : 분리 되어도 그 자체로도 독립적인 것.
2) Component의 장점
Component로 프로그램을 개발하면, 프로그램이 실행되는 도중에도 Component를 바꿀 수 있다.
-> 이를 위해서는 프로그램의 캡슐화가 필요하고, 동적으로 연결되어야 한다.
Component는 다른 언어나 개발툴로 만들어진 응용프로그램에서도 이용가능하다. 따라서 다른 언어로 개
발된 Component를 재사용할 수 있다.
* Component Object Model : 이를 위한 표준화된 방법
4. 인터페이스
COM Component와 해당 component를 사용하는 클라이언트 간의 상호 작용을 위한 약속. 서로 정의된 이
진 표준을 따르면 어느 플랫폼에서도 사용이 가능하다. COM인터페이스는 가상항수 테이블로서 구현이 된
다. 이는 C++가상함수 테이블과 동일하고, 인터페이스는 언어/구조 독립적인 함수의 테이블로서 구성됨
5. Component를 만들기 위한 규정
COM은 일반적으로 윈도우 환경 안에서 다음과 같이 패키지화 된다.
1) DLL내에 포함
객체는 스스로 실행할 수 없기 때문에, DLL내에서 패키지화 됨. DLL내에 포함된 객체는 클라이언트와 같
은 주소 공간에서 실행됨. In Process Server라고 부름
2) EXE내에 포함
exe에 포함되는 객체는 자신의 주소 공간을 확보함. Out of Process Server라고도 함. 매우 큰 프로그램
을 구현할 때 자주 사용됨
3) 원격 서비스처럼 다른 장소에서 제공
네트워크를 통하여 사용되면 '서비스 프로그램'이라고 부름
COM은 MS사가 표준화한 규정에 맞게 작성된 DLL또는 EXE프로그램을 의미. 이 COM Component를 사
용하는 클라이언트에는 다음과 같은 몇가지 제약이 있따.
* 언어 독립적이다.
언어독립적으로 구현되어야 다른 언어나 개발 툴에서 쉽게 통합하여 사용이 가능함.
* 이진화된 표준을 정의함
COM은 가상함수테이블을 메모리에 구축하거나, vtable을 통해 함수를 호출하는 표준을 정의함.
-> 이를 '이진표준'이라고 함
* 동적 연결이 가능해야 한다.
이미 사용중인 클라이언트와 연결 고리를 끊지 않고도 업그레이드가 가능해야 함
* 위치투명성을 제공해야 한다.
6. COM라이브러리
COM은 언어나 클래스 라이브러리가 아닌 표준화된 방법을 규정한 사양. 따라서 VC++에서는 COM라이브러리를 제공한다. API형식의 하수로 구성되어 있으며, COM Component개발에 있어 쉽게 개발할 수 있다는 장점이 있다.
내용 출처 - COM Bible
댓글