COM 의기초개념 (Basic Concepts of Component Object Model) COM (Component Object Model) 은 OLE 와액티브 X 기술의기초가되는개념으로인터페이스라는미리정의된루틴의세트를통해각객체들간의상호운용을가능하게해주는객체기반의프로그래밍 specification 이다. COM 은기본적으로소스코드수준의표준이아니라바이너리표준이다. 이때문에여러가지다른언어로객체를구현할수있으며, 서로다른플랫폼과다른주소공간에서실행과통신이가능하다. 또한, COM 객체들은유일한 identifier 가있어서생성과인터페이스로의접근이쉬우므로확장, 수정, 업데이트가용이하다. COM 에는 COM 객체의핵심적인기능을정의하고, COM 객체들의생성과관리를가능하게하는 API 함수의세트를정의하고있는표준인터페이스들의세트를포함한라이브러리를가지고있다. 또한, COM 은 OLE 와액티브 X 의기초가되는데, 이들기술들은운영체제의확장부분처럼동작하여이들 type 의객체들을생성하고조작할수있는라이브러리들을제공한다. COM 을기반으로하여개발자들은다른 COM 에기반한기술들과상호작용할수있는그들만의확장부분을생성할수있다. 델파이에는이런 COM, OLE, 액티브 X 응용프로그램의핵심적인요소를쉽게생성할수있는클래스들과마법사들이준비되어있다. Delphi object framework 에는하나의어플리케이션에서쓰이는간단한 COM-호환클래스들로부터 OLE 자동화서버와액티브 X 컨트롤에서쓰일수있는클래스들까지지원하고있다. 델파이를 COM-기반어플리케이션을개발하는데사용하여어플리케이션의내부적으로인터페이스를기반으로한세련된소프트웨어디자인을할수있으며, 윈도우 95 쉘확장이나 DirectX 와같은 COM 에기초한여러가지 API 객체들과상호작용이가능한객체들을생성해낼수있다. 델파이 4 가지원하는위저드로생성할수있는것으로는다음과같은것들이있다. - 단순한 COM 객체 - 자동화서버 - 자동화컨트롤러 - 액티브 X 서버와액티브폼 - 마이크로소프트트랜잭션서버 (MTS) 객체 자주쓰이는용어정의부터하겠다. 인터페이스 : 명확하게정의된목적이있는메소드프로토타입들의세트
COM 객체 : CoClass 라고불리는클래스의인스턴스로 COM 인터페이스들의메소드들을실제로구현한다. COM/ 액티브 X 서버 : COM 이나액티브 X 객체들을포함한모듈 (EXE, DLL, OCX). 클래스팩토리 : 지정된 CoClass 로부터 COM 객체를생성할수있는객체타입라이브러리 : 리소스로저장이가능한이진심볼파일로, COM 이나액티브 X 서버에대한데이터형정보를담고있다. COM 아키텍처의이해 이들 COM 객체가동작하는방식은아래그림과같다. 클라이언트어플리케이션이 ClassID 를가지고 COM 객체를생성하는요구를하면, OS 에서제공하는 COM 라이브러리 ( 윈도우 95 의경우 COMOBJ.DLL, OLE32.DLL 에구현되어있다.) 가시스템레지스트리에서해당되는 CLSID 를가진 COM 객체를찾게된다. 이때이 COM 객체는클라이언트어플리케이션의요구를서비스하는 COM 서버로동작하게되는것이다. 이렇게찾은 COM 객체의구현부분을찾아서해당인터페이스멤버함수의포인터를클라이언트의어플리케이션의해당부분에매핑시켜준다. 그런데이때 COM 객체의위치는하나의프로세스공간에있을수도있고, 다른작업공간에있을수도있으며, 심지어는다른컴퓨터안에있을수도있다. 이때 COM 객체의인터페이스포인터의위치를하나의프로세스공간에있는것처럼포장하는과정을마샬링이라고하며, 이때 COM 서버측의포인터를포장하는객체를스텁 (stub), 클라이언트어플리케이션측의객체를프록시 (proxy) 라고한다. 이를그림으로정리해보면다음과같다.
만약클라이언트어플리케이션에서크래쉬가일어나게되면 ( 예를들어클라이언트어플리케이션이동작하는컴퓨터가불의의사고로다운된경우 ) 클라이언트의프록시객체는파괴되며, 이와연관된서버측의스텁객체가커넥션이단절된것을감지하여클라이언트객체와연결된수만큼레퍼런스카운트를감소시키며, 이것이 0 이되면서버객체가파괴된다. 반대로, 서버객체가비정상종료되면클라이언트어플리케이션은프록시객체에서에러코드를받을수있게된다 (DLL 의경우에는클라이언트어플리케이션에도크래쉬가일어나면서비정상종료하게된다.). COM 어플리케이션의구성 COM 어플리케이션을구현할때에는다음과같은부분을제공해야한다. COM 인터페이스 객체가자신의서비스를클라이언트에게노출시키는방법이다. 스를연관된메소드와프로퍼티의세트로제공한다. COM 객체는인터페이 COM 서버 EXE, DLL, OCX 형태의모듈로 COM 객체를위한코드를포함하고있다. 이서버안에있으며, COM 서버는하나이상의인터페이스를구현한다. 객체들은 COM 클라이언트서버에서요구한서비스를얻기위해인터페이스를호출하는코드이다. 클라이언트는서버에서제공하는서비스가어떻게구체적으로동작하는지는모른다. COM 클라이언트중가장흔한것은자동화컨트롤러이다.
OLE 와액티브 X 객체 OLE, 액티브 X 객체들은비주얼할수도논비주얼할수도있으며, 클라이언트에서같은작업공간에서돌아갈수도있고, 다른작업공간에서돌아갈수도있다. 다른작업공간에서돌아가게만들거나 remote-procedure call 을쓸수있게하려면필요한인자들을 package 하고, unpackage 할수있어야한다. 위에서도설명했듯이이와같은과정을마샬링이라고하는데, 이렇게 RPC 를쓰거나프로세스공간을초월한어플리케이션작업을할때에는여러가지방법으로여러가지인자들이마샬링작업을거쳐야하며, 여러가지종류의 OLE 와액티브 X 객체들이서로다른방법의마샬링작업을하게된다. 다음표에생성이가능한 OLE 객체의 type 들을나열해보았다. OLE 객체비주얼작업공간통신타입라이브러리 OLE/Active 문서거의 In-process, cross-process Verbs for marshaling No OLE 자동화 일부 In-process, cross-process, or remote IDispatch automarshaling Recommended 액티브 X 컨트롤 거의 In-process IDispatch automarshaling Required 사용자정의인터 페이스객체 옵션 In-process, cross-process, remote Manual marshaling Recommended OLE 자동화서버들은 IDispatch 인터페이스를구현한객체들이다. IDispatch 는 IUnknown 에서파생되었기때문에 IUnknown 인터페이스도구현하고있다. IUnknown 인터페이스는 IDispatch 인터페이스의메소드들이 OLE 자동화객체의메소드와프로퍼티에접근하는동안서버객체가지원하는다른모든인터페이스들을관리한다. 다음그림은 IUnknown 과 IDispatch 인터페이스를지원하는객체의 IDispatch 인터페이스 vtable 의모식도이다.
OLE 자동화컨트롤러는 OLE IDispatch 인터페이스를이용해이인터페이스를구현한 OLE 서버객체에접근하는클라이언트이다. 컨트롤러는반드시먼저객체를생성하고, 그 IDispatch 인터페이스객체의포인터에해당하는 IUnknown 인터페이스를질의 (query) 로알아낸다. OLE 자동화컨트롤러는 OLE 자동화객체에다음의두가지다른방법으로접근이가능하다. - IDispatch 인터페이스를이용한다. - 만약듀얼인터페이스 (dual interface) 가정의된경우라면객체의가상함수테이블 (virtual function table, vtable) 이멤버함수를직접호출한다. 인터페이스라이브러리의이용 특별한 type 의객체를제작하거나사용할때에는그 type 에대한해당되는라이브러리나, 표준객체에대한규칙을참조해야한다. 다음에인터페이스라이브러리의 type 에대한요약과가능한확장성을기술하였다. 1. COM 인터페이스 COM 은인터페이스의표준라이브러리를정의하고있다. 여기에는인터페이스의기본적인기능을정의하는 IUnknown, 외부에서 COM 객체를인스턴스화할때필요한클래스 factory 객체를정의하는 IClassFactory 인터페이스등을포함한다. COM 인터페이스를구현하는클래스의제작에관심이있는개발자들은델파이에서제공하는 TInterfacedObject, TComObject, TTypedComObject, TComObjectFactory, TTypedComObjectFactory 클래스를참조하면도움이된다.
2. OLE/ 액티브 X 확장부분 OLE 라이브러리확장부분은많은수의객체 type 을지원하며, 각각의객체는지원할수있거나반드시지원해야하는인터페이스들의정의를가지고있다. OLE 그자체는아주일반적인목적의인터페이스들을많이제공하는데, 이런인터페이스는 IOle 로시작한다. OLE 처럼액티브 X 역시 COM 의구현부분이다. 액티브 X 기술을이용한공통적인어플리케이션에는 Active 문서, 액티브 X 컨트롤등이있다. 이기술은 COM 에대한확장부분으로개발된것으로크기와속도를최적화한기술이다. 3. 액티브도큐먼트 (Active document) 액티브도큐먼트는문서객체와컨테이너에대한인터페이스의라이브러리이다. 이라이브러리에서는그자신의인터페이스를이용해서컨테이너와객체어플리케이션간의링킹과임베딩을위한통신등의다양한서비스를제공한다. 액티브도큐먼트컨테이너를제작하는데관심이있는개발자는 TOleContainer 컴포넌트를이용하면된다. 4. OLE 자동화 OLE 자동화는 IDispatch 인터페이스의구현을필요로한다. OLE 자동화는서로다른작업공간에서의파라미터의전송과패키징, 객체의저장과객체이름의번역등을지원하는서비스를포함한다. OLE 자동화에관심이있는개발자는 IDispatch 인터페이스를구현하고있는 TAutoObject 클래스를이용하면된다. 5. 액티브 X 컨트롤 액티브 X 컨트롤은, 과거에 OLE 컨트롤이나 OCX 로불리던것으로, 액티브 X 라이브러리에있는인터페이스들을구현한객체를가리키는말이다. 이들인터페이스들은객체가이벤트를발생시키고, 데이터소스에바인딩이가능하고, 라이센싱을지원하는인터페이스를제공한다. 델파이는 TActiveXControl 과 TActiveForm 클래스를제공하며동시에쉽게액티브 X 객체를제작할수있도록위저드를제공한다. 6. 커스텀 / 서드파티인터페이스의구현 자기자신의라이브러리와규칙들을정의할수있다. 커스텀또는서드파티인터페이스를 구현하는객체를제작할때에는 TComObject, TTypedComObject, TAutoObject 를기초 클래스로하면된다.
클래스팩토리 COM 객체는하나이상의 COM 인터페이스를구현한 CoClass 의인스턴스이며, COM 객체는 CoClass 인터페이스에의해정의된서비스를제공한다. 클래스팩토리는 COM 객체를제작하고등록하는데사용하는객체이다. 클래스팩토리는 CoClass 를인스턴스화하는표준메커니즘을제공한다. 클래스팩토리를이용하여객체를인스턴스화하면클라이언트가유일한 identifier 만알게되면 CoClass 에대해다른것들은알필요가없어진다. 클래스팩토리는생성자 (constructor) 메소드와 argument 등을다룬다. 각각의 CoClass 정의에는클래스팩토리가있다. 클래스팩토리는하나이상의 CoClass 와관련이있을수있으며, 이들각각이인스턴스화될수있다. 어쨌든일단클래스팩토리자신이인스턴스화되면이것은특정클래스 identifier(clsid) 와연관이되며, 이것이생성자 (constructor) 에넘겨진다. 이파라미터는어떤 CoClass 가클래스팩토리에의해인스턴스화되는지를나타낸다. 그래서, 클래스팩토리클래스가하나이상의 CoClass 에적용되면각각의클래스팩토리인스턴스는오직하나의 CoClass 의인스턴스를생성할수있다. 1. CoClass 의인스턴스화 CoClass 는 CoGetClassObject 라는글로벌윈도우 API 함수를호출하여인스턴스화될수있다. 이함수는레지스트리에서 CLSID 를찾고, 서버의패스를알아내어서버를로드하고클래스팩토리인터페이스 ( 보통은 IClassFactory) 에다가포인터를넘긴다. IClassFactory 포인터는 CoClass 의인스턴스를생성할때쓰이는클래스팩토리의 CreateInstance 메소드를호출할때쓰인다. 위의과정을밟지않고, API 함수인 CoCreateInstance 를호출하면위의모든과정을한번에해준다. 일단서버를로딩하면 CoCreateInstance 는자동으로 CoGetClassObject 함수를호출하고, IClassFactory 포인터를통해서 CreateInstance 메소드를호출한다. 어쨌든클래스의여러개의인스턴스를생성할때에는하나의클래스팩토리를이용해서 CreateInstance 메소드를직접호출하는것이빠르다. CoGetClassObject 만이 IClassFactory 인터페이스포인터를제공할수있기때문에, CoCreateInstance 를호출하기보다는 CoGetClassObject 를호출하는것이빠르다. 2. 델파이의클래스팩토리클래스 객체가클래스팩토리가되려면 IClassFactory 인터페이스를지원해야한다. 델파이의 CoClass 들은그에해당하는클래스팩토리클래스들을가지고있다. 이들은 IClassFactory 인터페이스를구현하거나 IClassFactory2 인터페이스를지원한다.
IClassFactory2 인터페이스는라이센싱이필요한액티브 X 객체를지원한다. 델파이의클래스팩토리객체들은서버를포함한유닛의 initialization 섹션에서생성되어야한다. 이로인해서버가일단로드되면클래스팩토리는자동적으로사용이가능해진다. 델파이의 COM 서버클래스는 COM 또는액티브 X 서버의제작에쓰이는데, 여기에는클래스팩토리를관리하는메소드들을포함하고있다. 클래스팩토리에는 reference count 를하는기능이있기때문에서버는언제 unload 되어야하는지알수있다. COM, 액티브 X 서버 COM 서버는클라이언트어플리케이션이나라이브러리에서비스를제공하는어플리케이션이나라이브러리를말한다. COM 서버는클라이언트와같은작업공간에서동작하는 DLL 인 in-process 서버일수도있고, 클라이언트와다른작업공간이되같은기계안에서동작하는 EXE 파일인로컬서버일수도있으며, 클라이언트와다른기계에서동작하는리모트서버일수도있다. COM 서버는 COM 객체가존재하는모듈이다. COM 서버는 OLE 자동화객체, 액티브 X 컨트롤, 액티브폼에대한코드를담고있다. 델파이는액티브 X 서버가가지는기본적인기능들을캡슐화한클래스를가지고있는데, 그기능에는다음과같은것들이포함되어있다. 1. 서버의등록, 클래스의등록, 서버를로딩하거나언로딩하거나객체의인스턴스화를담당하는데필요한루틴들을 export 한다. 2. 서버에객체를구현하는데필요한클래스 factory 의생성과관리 3. 서버의 type, help 파일, 서버의이름, 타입라이브러리등의서버에대한핵심적인정보를제공한다. 델파이의서버클래스는타입라이브러리를필수로한다. 여기에는서버에서사용이가능한 객체와인터페이스에대한정보를담고있다. 마샬링 (marshaling) 기전 마샬링은클라이언트가다른프로세스나기계에있는원격객체의인터페이스함수를호출할수있도록해주는기전을말한다. 다른말로하면, 서버프로세스의인터페이스포인터를클라이언트프로세스에서사용할수있는포인터로바꾸고, 클라이언트의파라미터를원격객체의프로세스공간으로옮겨야한다. 어느인터페이스호출에서도클라이언트는 argument 들을스택에밀어넣고, 인터페이스포인터를호출하여함수를실행한다. 만약이때객체가 in-process 가아니면호출된함수는프록시에전달된다. 프록시는 argument 들을마샬링패킷에포장하고, 이를원격객체에
전달한다. 원격객체의스텁은이패킷을풀어서, argument 들을스택에집어넣고, 객체의구현부분을호출한다. 즉, 객체는클라이언트의함수호출하는방식을자신의프로세스에서자신의주소를이용하여재생성하는것이다. 어떤형태의마샬링을사용할것인가하는문제는 COM 객체가구현된방법에달려있다. IDispatch 인터페이스가제공되는경우에는표준마샬링기법을이용하게된다. 이방법은시스템표준 RPC 를통해통신하게된다. 자동화 (Automation) 자동화란어플리케이션이다른어플리케이션의객체를제어할수있는능력을말한다. 자동화객체의클라이언트는자동화컨트롤러 (automation controller) 라고하며, 서버객체를자동화객체 (automation object) 라고한다. 자동화는 in-process, 로컬, 원격서버에서모두사용이가능하다. 자동화의가장큰특징은다음의 2 가지이다. 1. 자동화객체는반드시객체의인터페이스와인터페이스메소드, 파라미터등의정보를기술해야한다. 이런정보는보통타입라이브러리에기록되며, 이를이용해여러가지작업을할수있게된다. 델파이 4 에서제작한자동화서버에도타입정보가포함된다. 2. 자동화객체는반드시메소드들을다른어플리케이션이접근할수있도록해야한다. 이를위해반드시 IDispatch 인터페이스를구현해야하며, 이를통해인터페이스의메소드와프로퍼티에접근할수있게된다. 액티브 X 컨트롤 액티브 X 컨트롤은 in-process 서버에서만돌아가는비주얼컨트롤로 OLE 컨테이너어플리케이션에플러그인될수있다. 액티브 X 컨트롤은자체로완전한어플리케이션이될수는없지만, 여러가지어플리케이션에서사용될수있는재사용가능한컨트롤이다. 액티브 X 컨트롤의프로퍼티, 메소드, 이벤트를사용하려면자동화기법을이용해야한다. 액티브 X 컨트롤은웹페이지에서많이사용되고있다. 그렇기때문에액티브 X 는현재웹에서 interactive 한컨텐트를제공하는표준으로점점자리를잡아가고있다. 델파이 4 에서는이런액티브 X 컨트롤을쉽게제작할수있는위저드를제공한다. 타입라이브러리 (type libraries) 타입라이브러리는 COM 객체에어떤인터페이스가존재하는지, 그리고각인터페이스메
소드 argument 들의수와데이터형등의정보를담고있다. 또한, CoClass 의 identifier(clsids) 와인터페이스의 identifier(iids) 그리고, 자동화인터페이스메소드에대한디스패치 identifier(dispids) 등도가진다. 타입라이브러리에는그밖에도다음과같은정보를담고있다. - 사용자정의인터페이스와연관된사용자정의데이터형정보 - 인터페이스메소드가아니면서도자동화나액티브 X 서버에의해 export 되는루틴 - 열거형 (enumeration), 구조체 (structure), 공용체 (union), 앨리어스, 모듈데이터형등에대한정보 - 다른타입라이브러리의타입기술에대한레퍼런스 타입라이브러리의생성방법과사용 지금까지의개발도구에서는 IDL(Interface Description Language) 또는 ODL(Object Description Language) 를이용하여스크립트를작성함으로써타입라이브러리를작성했다. 그리고, 이렇게작성한스크립트를컴파일러를동작시켜헤더파일을만들어사용해왔다. 델파이 4 는자동화서버나액티브 X 컨트롤위저드를사용할때타입라이브러리를자동으로만들어준다. 그리고, 타입라이브러리에디터를이용해서타입라이브러리의내용을보면서쉽게정보를편집할수있게해주며, 델파이는해당되는소스를자동으로업데이트한다. 타입라이브러리에디터는자동으로표준타입라이브러리를생성하고, 델파이용인터페이스파일 (.pas 파일 ) 에오브젝트파스칼문법으로인터페이스정의를한다. 외부사용자에게노출될객체들의타입라이브러리를작성하는것은매우중요한작업이다. 예를들면다음과같은것들이있다. - 액티브 X 컨트롤은액티브 X 컨트롤이포함된 DLL 에타입라이브러리가리소스로함께포함되어있기를요구한다. - 자동화서버를구현한어플리케이션은반드시타입라이브러리를제공해서, 클라이언트가 early 바인딩을사용할수있도록해야한다. - Vtable 바인딩을지원하는노출된객체들은반드시타입라이브러리기술되어야한다. 이는 vtable 레퍼런스가컴파일시에사용되기때문이다. - IProvideClassInfo 인터페이스를지원하는클래스에서인스턴스화된객체들은반드시타입라이브러리를가져야하는데, 델파이의 VCL 중에서는 TTypedComObjectClass 를상속한클래스들이해당된다. - Drag-and-drop 에는타입라이브러리가반드시필요한것은아니지만, 제공되면객체를확인할때유용하다.
만약인터페이스를단지어플리케이션내부에서만사용할것이라면타입라이브러리는생성 할필요가없다. 타입라이브러리의접근방법과활용 이진타입라이브러리는보통리소스파일 (.res) 의일부이거나.tlb 파일확장자를가진독자적인파일로존재한다. 일단타입라이브러리가생성되면, 오브젝트브라우저 (object browser), 컴파일러등의도구가특별한타입인터페이스를통해타입라이브러리에접근할수있다. 이러한타입인터페이스에는다음과같은것들이있다. 인터페이스 설명 ITypeLib 타입라이브러리에접근할수있는메소드를제공한다. ITypeInfo 타입라이브러리에포함된각객체에대한설명을제공한다. 예를들어, 브라우저는 이인터페이스를이용하여타입라이브러리에서각객체에대한정보를뽑아낸다. ITypeComp 컴파일러가인터페이스에바인드할때필요한접근정보를빨리뽑아낼수있다. 델파이는다른어플리케이션에서타입라이브러리를 import 하거나, 이를사용할수있다. COM 어플리케이션을위해사용된대부분의 VCL 클래스는타입라이브러리와실행중인객체의인스턴스에서타입정보를불러오거나저장할때사용되는핵심인터페이스를제공한다. TTypedComObject VCL 클래스는타입정보를제공하는인터페이스를지원하며, 액티브 X 객체프레임웍에서사용되는기반클래스이다. 어플리케이션에서타입라이브러리를요구하지않아도, 타입라이브러리를사용하면다음과같은잇점을얻을수있다. - 데이터형검사를컴파일시에할수있다. - 자동화에서 early 바이딩을사용할수있으며, vtable 이나듀얼인터페이스를지원하지않는자동화컨트롤러가 dispids 를컴파일시에인코드할수있으며, 이로인한런타임수행성능의향상을얻을수있다. - 타입브라우저 (Type browsers) 로라이브러리를스캔할수있으므로, 클라이언트가개발자가만든객체의특징을볼수있게된다. - RegisterTypeLib 함수를이용하여노출된객체들을레지스트리데이터베이스에등록하는데사용할수있다. - 시스템레지스트리에서객체를제거할때에도 UnRegisterTypeLib 함수를사용할수있다. - 자동화작업이타입라이브러리에서얻은정보를이용하여파라미터를포장하게되므로,
로컬서버에접근하는성능이향상된다. 액티브도큐먼트 (Active Documents) 과거에 OLE 도큐먼트로불리던액티브도규먼트는연결 (linking) 과임베딩 (embedding), drag-and-drop, 비주얼편집 (visual editing) 을지원하는 COM 서비스의세트이다. 액티브도큐먼트는사운드클립, 스프레드시트, 텍스트와비트맵과같은다른포맷의데이터와객체를통합할수있다. 액티브 X 컨트롤과는달리액티브도큐먼트는 in-process 서버로한정되지않고, 프로세스의경계를넘어서사용될수있다. 참고로, 액티브도큐먼트의스펙을살펴보면프로세스의경계를넘어설수있도록마샬링이지원되지만, 사실상액티브도큐먼트는동일기계상의다른프로세스에서는사용될수있지만원격서버에서는동작하지않는다. 이는액티브도큐먼트가사용하는데이터형이윈도우핸들, 메뉴핸들과같이주어진기계상의시스템에특정한것들을사용하기때문이다. 대부분이비주얼하지않은자동화객체와는달리, 액티브도큐먼트객체는다른어플리케이션에서도비주얼하다. 그러므로, 액티브도큐먼트객체는디스플레이나출력장치에비주얼하게보여지는데사용되는프리젠테이션데이터 (presentation data) 와객체를편집할때사용되는원시데이터 (native data) 의 2 가지데이터종류를가지게된다. 액티브도큐먼트객체는도큐먼트컨테이너이거나도큐먼트서버일수있다. 델파이 4 는액티브도큐먼트를생성하는자동화위저드를제공하지않지만, TOleContainer VCL 클래스를이용하여이미존재하는액티브도큐먼트를연결하거나임베딩할수있다. 또한, TOleContainer 는액티브도큐먼트컨테이너로사용할수도있다. 액티브도큐먼트서버에대한객체를생성하려면 COM 기초클래스하나를사용하고, 지원하고자하는객체데이터형에대한적절한인터페이스를구현하여야하며, 위저드는제공되지않는다. COM 과 VCL 클래스 델파이에서 COM 기술을구현한유닛을살펴보면, 우선 COM 기술의 API 세트와인터페이스정의를오브젝트파스칼의형식에맞도록선언해놓은부분이 ActiveX.pas 와 Ole2.pas, OleCtl.pas, OldDlg.pas 유닛에기록되어있다. ActiveX.pas unit 은델파이에서지원하는인터페이스선언문을사용하여 COM 인터페이스를재선언하고, COM 라이브러리 DLL 에서지원하는 API 세트를정의해놓은유닛이다. 그러므로, COM 기술을위한모든 VCL 클래스들은기본적으로이유닛을사용해야만한다. 이렇게델파이가액티브 X 기술을지원하기위해서제공하는클래스를 DAX(Delphi ActiveX Framework) 라고한다. 실제로 COM 객체클래스에서가장기초클래스가되는 TComObject, TAutoObject, TComClassFactory 등의클래스는 ComObj.pas unit 에구현되어있다. 델파이의모든 COM 객체는 TComObject 클래스에서상속받은객체라고할수있는데, 그선언부분은다
음과같으며, 이해를돕기위해필자가약간의주석을달았다. TComObject = class(tobject, IUnknown, ISupportErrorInfo) { 액티브 X.pas unit 에선언된 IUnknown, ISupportErrorInfo 인터페이스를구현한클래스임을나타내 는코드 } private FRefCount: Integer; // 내부적인참조계수로사용되는변수 FFactory: TComObjectFactory; //COM 객체의클래스 factory FController: Pointer; //Aggregation 된경우의 IUnknown 의구현부분 function GetController: IUnknown; protected // 아래의메소드는 IUnknown 자체의구현이다. function IUnknown.QueryInterface = ObjQueryInterface; //QueryInterface 를 TComObject.ObjQueryInterface 가구현한다는의미 function IUnknown._AddRef = ObjAddRef; function IUnknown._Release = ObjRelease; // 다른인터페이스들에대한 IUnknown 메소드 function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall; // 해당 IID 를받아서 IUnknown 의 QueryInterface 를실행 function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; // 아래의메소드는 ISupportErrorInfo 인터페이스를구현한다. function InterfaceSupportsErrorInfo(const iid: TIID): HResult; stdcall; public constructor Create; //Aggregate 의부분이아닌 COM 객체를생성하는메소드 constructor CreateAggregated(const Controller: IUnknown); //Aggregate 된부분으로서의 COM 객체의생성을담당하는메소드 constructor CreateFromFactory(Factory: TComObjectFactory; const Controller: IUnknown); // 실제 constructor 역할을하는메소드로 Create, CreateAggregated 메소드에의해호출된다. COM 객체에메모리를할당하고프로퍼티들을설정한다.
destructor Destroy; override; //COM 객체를파괴하는메소드 procedure Initialize; virtual; // 가상함수로초기화에쓰인다. function ObjAddRef: Integer; virtual; stdcall; function ObjQueryInterface(const IID: TGUID; out Obj): Integer; virtual; stdcall; function ObjRelease: Integer; virtual; stdcall; function SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): HResult; override; property Controller: IUnknown read GetController; // 컨트롤러가되는 IUnknown 인터페이스 property Factory: TComObjectFactory read FFactory; property RefCount: Integer read FRefCount; end; {COM class } TComClass = class of TComObject; //TComClass 클래스의정의 TComObject 는클래스 identifier 를가지는 COM 객체에대한기초클래스이다. 이때 CLSID 를사용하는데이것은클래스를데이터베이스레지스트리에등록하고클래스팩토리를통해외부에인스턴스화하는데사용된다. TComObject 의클래스팩토리는 TComObjectFactory 가담당하며, 클래스팩토리의프로퍼티에서이름, 설명, CLSID 등의 TComObject 클래스의여러가지정보를제공한다. 또한, TComObjectFactory 메소드를사용하여 TComObject 클래스를레지스트리에등록하고인스턴스화할수있다. TComObject 는하나의 COM 객체로인스턴스화될수도있고, aggregate 의한부분으로인스턴스화될수도있다. 만약인스턴스화된 COM 객체가 aggregate 의내부객체라면그 IUnknown 인터페이스메소드가적절한컨트롤러인터페이스에의해동작하여 aggregation 을지원하게된다. 결과적으로내부 COM 객체에의해구현된모든인터페이스들은인터페이스참조가생길때마다참조계수 (reference count) 가직접적으로영향받지않고, 컨트롤러인터페이스에의해영향받는다. 마지막으로 TComObject 는 ISupportErrorInfo, InterfaceSupportsErrorInfo 를구현한다. 그러므로, OLE 예외처리와 safecall 호출규칙을지원한다. 델파이의 COM 지원은이렇게 TComObject 를기초클래스로해서풍부한 VCL 클래스로이루어져있다. 이들중가장중요한클래스들은 TTypedComObject, TAutoObject, TActiveXControl 등을들수있다. 이들중 TTypedComObject 와 TAutoObject 는 ComObj.pas unit 에구현되어있으며, TActiveXControl 의 AxCtrls.pas unit 에구현되어있다. AxCtrls.pas unit 에서는 VCL 클래스를액티브 X 컨트롤로전환하기위한 TActiveXControl 클래스의많은인터페이스를구현하고있다.
정리 (Summary) 이번장에서는델파이 4 와 COM 에대한기초적인개념설명과내용을알아보았다. COM 과 CORBA 에대해서는델파이가많은일을해주지만, 기초적인개념을이해하고있어야제대로된어플리케이션을만들수있다. 다음장에서는이번장의개념을바탕으로실제 COM 인터페이스를활용하고, COM 객체를만드는방법에대해서알아보도록할것이다.