본문스크랩 나의 COM(Component Object Model) 경험담 #1


나의 COM(Component Object Model) 경험담 #1

 

우선 앞으로의 모든 내용은 반말로 나갑니다. 기분 나쁘시면 읽지 않으셔도 됩니다. 그리고 어떠한 질문도 받지 않습니다. 답할 자신도 없습니다. 앞으로 몇 차례가 더 나갈지는 모르겠습니다. 그냥 제가 (X)리는 데로 할 생각입니다. 그럼 읽지 않으실 분들은 지금 마이크로소프트의 워드 창을 닫으시기 바랍니다. (–;;) 여기저기서 워드 닫는 소리가 들리는 군요. ^^;

그리고, 이 문서의 내용은 언제든지 변경될 수 있음을 알려드립니다.

경험담 #1은 com 의 개념 잡기 입니다. 최대한 쉬운 말로 나갑니다. 기술적 용어를 최대한 배제하겠습니다. 저 같은 분들을 위해서 입니다.

그럼 시작하겠습니다.

내가 COM을 처음 접했던 것이 언제인지 기억이 나질 않는다. 아마도 꽤 오래된 것 같다.

그 당시 기억을 떠올리면….

마이크로소프트에서는 앞으로 모든 프로그래밍은 COM으로 통합 될 듯이 광고를 했다.

난 여기에 현혹 되었고 ‘그래 내가 앞으로 가야 할 길은 이것이다’ 라며 공부를 시작하였다. (왠지 있어보일 것 같은 생각도 있었다.)

하지만, C++, MFC 조금 할 줄 안다고 해결될 문제가 아니었던 것을 그 당시에는 전혀 몰랐었다. 마치 사막에서 우물을 파는 듯한 느낌(이 보다 더한 느낌이었을지도 모른다.)이었고 도대체가 진도가 나아가질 않았다.

그리고 COM의 수박 겉 핥기만 하고 나서 잠시 그 쪽을 접었다.

한참 시간이 흘렀다.

그리고 다시 COM을 쓸 일이 생겼다. 다시 하고 싶지 않았지만 어쩔 수 없이 해야 했다. 그러면서 자연히 과거의 기억이 떠올랐다. 그 당시 왜 그렇게 COM 공부가 어려웠을까 생각해 보았다. 정답은 너무 세부적인 부분에 신경을 쓴 것이 실패 요인이었다. 왜 COM을 써야 하는지 이유를 몰랐던 것이다. 그리고 COM 개념을 확실히 잡고 들어가지 않은 점도 간과 할 수 없는 실수였다.

IUnknown 이 어떻고 QueryInterface()가 어떻고 Proxy는 머고는 전혀 중요하지 않았던 것이다.

이것은 MFC 프로그래밍을 할 때 WinMain()을 전혀 모르고 프로그래밍을 해도 문제가 없는 것과 같은 것이었다.(여기서 WinMain()을 꼭 알아야 한다고 우긴다면 난 할말이 없다.)

마이크로소프트의 그 당시 광고처럼 COM은 현재 거의 모든 마이크로소프트의 제품들의 근간 기술이 되었다. ‘.NET’ 이후로 COM이 더 이상 업그레이드가 없을 지라도 COM이 없는 Windows는 상상도 못할 상황이 되어 버렸다.

그렇다면 이제 본격적으로 COM 이 놈이 어떤 놈인지 알아봐야 한다.

코딩은 나중에 하겠다. 처음부터 코드가 들어가면 이 글을 읽다가 바로 나가는 사람이 있을

것 같아서 처음에는 간단히 개념만 설명하겠다. 함수만 들어가도 머리를 싸 메는 사람도 있

을 것 같아서 함수도 언급하지 않겠다. 하지만 경험담 #2 부터는 단단히 맘 먹어야 할 것

이다.

먼저 이야기 해 둘 것이 있다. 헷갈릴 까봐 미리 말해둔다. COM 역시 대부분 .DLL로 만들어진다. 따라서 앞으로 언급될 DLL은 COM이 아닌 일반 DLL이다. 그리고 COM은 COM으로 언급할 것이다.

현재 COM과 가장 비슷하게 설명 될 수 있는 놈이 무엇일까? 바로 DLL이다. 하지만, 분명한 차이점이 있다. COM이 DLL과 같은 놈이었다면 COL(Component Object Library)이 되었을 것이다. 아니, 아예 나오지 않았겠지(그래 분명히 나오지 않았을 것이다.)

그럼 라이브러리와 모듈의 차이는 무엇일까? 바로 독립성이다. DLL이 실행파일에 의존한다는 것은 DLL의 가장 큰 취약점이라고 할 수 있다. DLL을 업그레이드 한다는 말은 실행파일을 다시 그 DLL을 가지고 다시 컴파일 해야 한다는 말이다. 물론 DLL 하나에 실행파일 하나라면 굳이 이럴 필요가 없을지도 모른다. 하지만 DLL의 목적중의 하나가 공유가 아니었던가. 나 혼자 그 DLL을 쓰는 것이 아니다.

옛날 도스시절 우리는 많은 라이브러리를 사용했었다. 하지만, 이것은 정적 라이브러리 였다. 그리고 응용 능력이 좋은 마이크로소프트는 동적 라이브러리라며 COM을 광고하듯이 마치 신기술인양 DLL을 광고했던 기억이 난다. 이 동적 라이브러리는 실행 파일들의 공통된 부분을 이진형태(exe파일 같은)로 떼어내서 실행 파일들 끼리 ‘우리 그 부분은 너랑 나랑 똑같이 필요하니깐 사이 좋게 나눠 쓰자’ 하는 것과 같다. 정적 라이브러리가 컴파일 시 실행파일에 포함되는 것과 비교한다면 엄청난 발전이라 할 수 있다.

모든 제품이 그러하겠지만, 처음 나올 때는 생각 못했던 문제점이 발생하기 시작한다. DLL에서 바로 앞에서 언급한 업그레이드 문제가 그것이다. 왜 문제일까?

잘 생각해보자. 여기서 부터는 조금 머리가 아파올 것이다. 가장 간단하게 vc++6.0으로 프로그래밍을 할 때 컴파일을 하면 기본적으로 mfc42.dll과 연결된다. 물론 static으로 컴파일한다면 DLL을 신경 쓸 필요가 전혀 없어지겠지만, 이것은 모든 필요한 DLL들이 실행파일 모듈에 포함되기 때문에 하드디스크와 메모리 낭비를 가져오게 될 것이다. 자 그럼 이제 .net이 나온 시점에서 생각해보자 vc++.net은 mfc70.dll을 사용한다. 그렇다면 기존에 만든 프로그램들은 mfc70.dll을 사용할까? 그렇지가 않다 기존 프로그램들은 mfc42.dll 을 그대로 사용하고 vc++.net으로 만든 프로그램들만 mfc70.dll을 사용한다. 결국 프로그램이 새로 나올 때마다 윈도우시스템 디렉터리에는 DLL들이 쌓이게 될 것이고 디스크 메모리는 어쩔 수 없이 낭비 되어 버린다. mfc70.dll을 사용하고 싶다면 기존 프로그램을 새로 다시 mfc70.dll로 새로 컴파일 한다면 mfc70.dll만 있어도 가능할 것이다. 하지만 누가 이 미친 짓을 하겠는가? 사용자들 보고 ‘업그레이드 되었으니 새로 다운 받으십시오.’ 이렇게 e-mail을 보낼 것인가?

이러한 문제는 .DLL 에서 다른 .DLL을 참조할 때도 똑 같은 상황이 발생할 것이다. 결국 .DLL이나 .EXE나 내부는 같기 때문일거다.

여기서 의문을 제기하는 사람이 분명 있을 것이다. ‘그러면 같은 이름을 쓰면 되지 않겠냐?

내용은 업그레이드 하더라도 파일 이름을 mfc42.dll 그대로 쓰면 되지 않느냐?’ 맞다 그대로 쓰면 된다. 하지만, 그렇게 쉬운 작업이 아니다. 이것이 해결 되었다면 굳이 COM이 나오지 않았을 지도 모른다.

그럼 왜 불가능한지 알아보자. 한마디로 얘기 하자면 DLL 설계 자체가 처음부터 잘못 되었기 때문이다. 어플리케이션에서 DLL에 있는 함수를 참조하는 기술은 마이크로소프트에서 아무 생각 없이 구현만 되면 된다고 생각하고 만들었을 것이다. 필요성조차 느끼지 못했을 수도 있다. DLL의 경우 자체 포함된 함수를 서수정보에서 인식할 수 있게 해 놓았다. 따라서 업그레이드 해서 그 서수정보가 바뀐다면 기존 어플리케이션에서는 그 함수들을 인식하지 못한다. 물론 새로 컴파일 하면 가능하겠지만 이것은 커다란 단점이다. 그럼 어느 정도 이해가 되었을 것이다. 정말 내부적인 부분까지는 나도 정확히 모르겠다. 이 부분에서 자세히 알고 싶은 사람은 Application for windows (fourth edition, Jeffrey richter)를 참조 하면 되겠다. 아마 이것만으로도 많이 부족할 것이다. 그렇다면 type-safe linking, name mangling 이라는 용어도 찾아보면 될 것 같다.(과연 실제로 찾아볼 사람이 있을지는 의문?)

잠시 머리를 식힐 겸 미래의 프로그래밍 방법이 어떻게 진행 될지 생각해보자. 많은 사람들이 앞으로 프로그래밍은 조립형식이 될 것이라고 말하고 있다. 필요한 컴포넌트를 구해서 조립만 하면 원하는 프로그램을 완성할 수 있게 될 것이라고 말한다. 내가 생각하기에도 컴퓨터가 지능을 가지지 않는 이상은 어플리케이션 프로그래머는 컴포넌트의 관계를 설정해 주는 직업이 될 것 같다. ‘너랑 너는 이렇게 연결 되야 해 넌 재랑 통신 해야 해’ 하고 정의만 해주면 되는 것이다.

참고로 http://www.componentsource.com/ 를 참조 해보면 좋을 것이다. 이곳은 각종 컴포넌트를 만들어 놓고 파는 곳이다. 돈만 많이 준다면 소스까지도 준다.

그렇다고 누구나 할 수 있는 직업이 될 것이라는 얘기는 아니다. 각 컴포넌트의 특징을 잘 알아야 할 것이고 연결방법 등을 공부해야 하고 하루에도 수십 가지의 컴포넌트들이 쏟아지게 될 것이기 때문에 공부하는 것도 고생일거다. 결국, 먼(?) 미래에는 프로그래머는 컴포넌트 개발자를 가르키는 말이 될 것이고 어플리케이션 프로그래머는 다른 말로 바뀔 듯 싶다. 일반 자동차 영업하는 사람처럼 말이다. 에어백 넣어드릴까요? 알루미늄 휠은 어떻게 할 건가요? ABS는요? 등등…

내가 하고픈 말은 이런 가능성을 조금이라도 보여준 것이 바로 COM이라는 것이다. 하지만, 앞으로의 COM이 어떻게 될지 아직 아무도 장담하지 못한다. 이유는 바로 .NET 때문이다. 자세한 이유는 나중에 언급하겠다.(결국 이것도 인터페이스 때문이다. 인터페이스가 문제가 있다는 것이 아니라 .NET 객체 역시 인터페이스를 지원한다는 것이다. 개인적으로 업그레이드된 COM이라고는 하고싶지는 않다. .NET 객체는 .NET 객체일 뿐이다. Versioning문제의 해결 역시 .net 의 엄청난 장점이다.)

다시 COM으로 돌아 와 보자.

COM 에서 가장 어려운 부분이 인터페이스의 이해부분 이었던 걸로 기억한다.. 하지만 이것만 확실히 한다면 COM은 끝난 거나 다름없다. 마치 옛날 C언어를 할 때 ‘포인터는 마녀다. 하지만, 그 마녀를 잡는다면 마녀의 힘을 얻을 것이다’라고 한 것과 비슷한 것 같다.

인터페이스가 뭘까? 많은 사람들이 여기서 막혀버린다. 인터페이스에 대해서는 말도 많고 탈도 많다. 내가 생각하기에는 가상함수가 어떻고 저떻고는 나중에 생각해야 할 문제이다. 인터페이스의 말에 대한 어원을 생각해보자. ‘접촉면’ 이란 단어가 가장 먼저 생각날 것이다. 우리가 윈도우를 쓰다 보면 인터페이스란 말이 나온다. 사용자 인터페이스가 어떻고 저떻고 그런말을 많이 들어봤을 것이다. 즉, 사용자와 윈도우간의 연결을 해주는 부분이라고 해도 좋을 것 같다. 하지만 이것은 개념상의 정의일 뿐이다.

우리는 어떻게든 이해가 목적이기 때문에 쉽게 생각하자. 황당한 예를 들더라도 이해만 하면 된다.

그럼 그 황당한 예를 보자.

먼 미래 인류는 우주로 진출하게 된다. 그리고 사람들은 작은 우주선을 타고 이별 저별 여행 다니면서 외계인도 만난다. 그리고 우주공간 곳곳에 고속도로의 휴게소 처럼 우주 정거장이 있다. 물론 혹성이나 행성에도 있다.

하나의 우주선이 정거장에 접근하면서 정거장의 출입구와 우주선의 출입구를 정확이 도킹한다. 그리고 긴 연료호스가 나와 정거장의 연료공급 구멍에 정확히 일치시킨다. 사람들은 정거장에서 맛있는 것도 사먹고 화장실도 가기 위해 출입구를 통해 왔다 갔다 하고 그 동안 연료는 자동 공급되고 있다.

하루에도 몇 백대의 작은 우주선들이 이 정거장에 도킹(?)했다가 떨어지고 그럴 것이다.

수도 없이 많은 우주선들이 있을 테고 이 도킹 부분이 틀린 우주선은 이 정거장에 가까이 접근은 가능하겠지만 도킹이 불가능하기 때문에 사람이 타고 내릴 수는 없을 것이다. 잘못했다가는 구멍이 생겨서 내장이 다 터져 우주미아가 될지도 모른다. 정거장에서는 출입구와 연료공급 구멍의 크기를 정확히 제한 해 놓았기 때문에 작은 우주선들은 이 출입구 크기에 맞게 도킹장치를 만들기만 하면 사람들이 내리고 타는 데는 문제가 없을 것이다. 잘만하면 외계인(ET)들도 도킹장치를 만들어서 접근이 가능할 것이다. 그리고 외계인들은 자기 나름대로의 도킹장치가 있을 것이고 지구인이 만든 정거장에서 서비스를 받기 위한 도킹장치를 따로 만들 것이다. 한 순간에 외계인 자신의 도킹장치를 포기하구 지구정거장에 맞춰서 바꾸진 못할 것이다. 결국 자기 것은 왼쪽에 만들고 지구인을 위한 것은 오른쪽에다 만든다거나 했을 것이다. 하나만 고집하다가는 신기하게 생긴 지구인 구경을 평생 못하고 죽는 비참한 외계인도 생길 것이다.

여기서 바로 이 정거장의 도킹장치가 인터페이스가 되는 셈이다. 그럼 정거장은 COM이 되는 건가? 그렇게 생각하는 것이 쉽겠다.

결국 인터페이스는 출입통로 그 이상도 그 이하도 아니다. 우리는 그 연료 인터페이스를 통해 연료도 공급 받고 출입구 인터페이스를 통해 음식도 공급 받을 수 있고 왔다 갔다 할 수도 있다. 즉 서비스를 받을 수 있는 것이다.

이 서비스 내용은 정거장마다 경쟁이 심해져서 연료를 10원 깎아 준다거나 화장지를 하나 더 준다거나 음식값을 싸게 해준다거나 해서 정거장마다 틀리다. 갈수록 서비스의 질이 나아지고 있는 것이다.(그럼 DCOM 은 호출 정거장인가? 호출하기만 하면 와서 연료도 주고 음식도 팔고 하는 그런 것. ^^)

그럼 DLL을 비슷하게 예를 들어보자. DLL은 구식 정거장이다. 정거장이라고 말하기도 부끄럽다. 연료를 넣는 자판기라고 부르는 것이 적당할 것 같다. 컵라면 자판기도 옆에 있다. COM이라는 정거장과 경쟁하기 위해서는 연료를 넣고 나면 화장지도 줘야 한다. 그럼 자판기에 화장지가 나오게 만들어야 한다. 결국 새로운 화장지를 주는 기능이 추가된 자판기로 교체를 해야 하는 불상사가 생긴다. 즉 서비스의 업그레이드를 할 때마다 이 자판기 자체를 바꿔야 한다. 하지만, 이것도 문제가 있다. 이전에 우주선은 새로운 자판기 사용법을 모르기 때문에 옛날 자판기를 그대로 놔두길 원하는 것이다. 자판기 회사는 결국 구식 자판기와 신식 자판기를 옆에 나란히 두어야 했던 것이다.

유지비도 많이 든다. 전기세가 장난이 아니었던 것이다. 자리세도 점점 많이 내야 한다. 결국 자판기 회사는 망하는 중이다.

이 예가 맘에 들지 않는다면 자신이 새로 적용을 시켜 예를 만들어 적용시켜도 좋을 것이다.

자신의 COM개념을 정립할 수만 있다면 어떠한 예도 좋다.

앞으로 해보겠지만 실제 COM을 구현해보면 생각보다 쉬운걸 알 수 있다. 그냥 DLL 만들듯이 만들면 된다. 그리고 필요한 기능끼리 잘 묶어서 인터페이스에서 정의 하면 된다. 물론 이 방법은 기존 DLL을 COM으로 업그레이드 할 때 유용하게 사용할 수 있다. 하지만, 이왕이면 인터페이스를 먼저 설계하고 함수들을 추가하는 것이 있어보이지 않겠는가? 왠지

설계능력을 갖춘 것처럼 보이니깐 말이다. (앞으로 여기서 골 때리는 말들이 많이 나온다.

가상함수니 가상함수 테이블이니 하는 그러한 것들이다. 하지만, 이것은 단지 우리가 약속만 지키면 끝이다. 실제 구현부분은 별개라는 얘기다.)

난 많은 책들에서 COM의 필요성을 봐왔다. 다들 DLL의 단점 기존 소프트웨어 공학의 단점, 컴포넌트 기반의 소프트웨어의 장점 등을 언급하면서 COM을 해야 한다고 부추긴다.

하지만, 난 돈으로 생각해서 그 필요성을 느낀다.

앞의 예에서 물론 우주선을 운영해서 사용자들로부터 요금을 받을 수도 있다.

하지만, 실생활에서 버스나 택시 기사들이 돈을 많이 버는가? 그렇지 않다는 것을 잘 알 것이다. 가장 쉽게 돈을 버는 방법은 자리를 제공해 자리세를 받던가 지나다니는 우주선으로부터 통행료를 받는 것이 가장 쉬울 것이다. 하지만, 이것은 국가나 대기업이 하고 있는 일이다. 마이크로소프트나 선이나 IBM 등등 이런 회사들이 이미 굳건히 지키고 있다.(결

국 .NET의 웹 서비스도 이러한 돈벌이가 아닐까 싶다.)

그럼 우리는 이 정거장을 운영하는 수 밖에 없다. 이것이 우리가 가장 쉽게 많은 돈을 벌 수 있는 방법인 것이다. 하지만 다른 정거장과 구별되는 무엇인가가 있어야만 경쟁에서 살아 남을 수 있다. 아니면 자리를 잘 잡던가.

오늘은 여기서 마치겠다.

다음 경험담부터 서서히 정거장 만들기에 들어갈 것이다. 언제 시작할지는 모르겠다. 앞에서 언급했듯이 내 맘이다. 우리도 돈을 좀 벌어야 하지 않을까?

 

 

e-mail :icoddy@hotmail.com

msn id :icoddy@hotmail.com

 – 박성규 –

 


답글 남기기

이메일 주소는 공개되지 않습니다.