ISLab ICE HUFS COM Component Object Model Component
ISLab ICE HUFS COM Component Object Model Component Programming
ISLab ICE HUFS 0. 배경 Component Programming
객체 지향 (Object Orientation) • 현재의 소프트웨어 기술 – Component-based Distributed Computing • 객체 – Component or Application – Code+Data • 상용화 된 분산 객체 지원 미들 웨어 – Microsoft - COM / OMG - CORBA / Sun - EJB ISLab ICE HUFS Component Programming 3
COM 의 역사 - 1 • OLE 1 – compound document 지원 – DDE (Dynamic Data Exchange) • OLE 2 – COM으로 완전히 재 작성됨 – OLE Automation 과 OLE Control ISLab ICE HUFS Component Programming 4
COM 의 역사 - 2 • Active-X – – OLE Control → Active-X Control OLE Automation → Automation Active-X Document Active-X Scripting ISLab ICE HUFS Component Programming 5
왜 COM 인가 • 요구 조건 – – – Component Interoperability Robust evolution (versioning) Language independence Location transparency Scalability • COM ISLab ICE HUFS Component Programming 6
ISLab ICE HUFS 1. 인터페이스(Interface) Component Programming
a COM Object ? ISLab ICE HUFS Component Programming 9
인터페이스(Interface)의 예 1 • 자동차 운전 인터페이스 struct ICar. Control { virtual void Rotate. Handle( int n. Angle ) = 0; virtual void Set. Gear( int n. Level ) = 0; virtual void Accelerate( int n. Rpm ) = 0; virtual void Break() = 0; virtual int Get. Speed() = 0; }; ISLab ICE HUFS Component Programming 10
인터페이스(Interface)의 예 2 • 라디오 인터페이스 struct IRadio { virtual void Set. Volumn( int n. Loudness ) = 0; virtual void Tune( double d. MHz ) = 0; }; ISLab ICE HUFS Component Programming 11
인터페이스의 상속 struct IStereo. Radio : public IRadio { virtual void Set. Mode( bool b. Stereo ) = 0; }; struct IStereo. Radio 2 { virtual void Set. Volumn( int n. Loudness ) = 0; virtual void Tune( double d. MHz ) = 0; virtual void Set. Mode( bool b. Stereo ) = 0; }; struct IAudio : public IRadio, public ICD { }; ISLab ICE HUFS Component Programming 12
인터페이스의 사용 (상상도) CTico* p. My. Car = new CTico( “경기”, 2, “로”, 2047 ); ICar. Control* p. Control = p. My. Car->Get. Control. Interface(); IRadio* p. Radio = p. My. Car->Get. Radio. Interface(); p. Radio->Tune( 91. 9 ); p. Radio->Set. Volumn( 10 ); p. Control->Set. Gear( 1 ); p. Control->Accelerate( 3000 ); p. Control->Set. Gear( 2 ); p. Control->Rotate. Handle( 10 ); : CTico ISLab ICE HUFS Component Programming 13
IUnknown: : Release IUnknown: : Add. Ref • 객체의 유지와 소멸을 관리 – Reference Counting – Add. Ref : Counter 증가 – Release : Counter 감소 • Query. Interface – 내부적으로 Add. Ref()를 호출함 ISLab ICE HUFS Component Programming 17
Reference Counting Release Query. Interface 1 1 2 0 Release Query. Interface ? ? ? ISLab ICE HUFS Component Programming 18
Reference Counting (cont’d) ULONG CTico: : Add. Ref() { return ++m_n. Ref; } ULONG CTico: : Release() { m_n. Ref--; if ( m_n. Ref > 0 ) return m_n. Ref; delete this; // suicide return 0; // do not ‘return m_n. Ref; ’ } ISLab ICE HUFS Component Programming 19
Calling Convention • __stdcall, __cdecl – 모두 함수 전달 인자를 스택에 오른쪽에서 왼쪽으로 push – 스택을 책임지는 자 • __stdcall : callee • __cdecl : caller ISLab ICE HUFS Component Programming 20
Calling Convention (cont’d) • 예 int __stdcall do_it( int a, int b ) { return 0; } int __cdecl do_that( int a, int b ) { return do_it( a, b ); } : do_that( 1, 2 ); ISLab ICE HUFS Component Programming 21
HRESULT type • HRESULT 구조 – typedef LONG HRESULT; // -_-; 31 30 29 28 27 26 ~ 16 S R C N r Facility 15 ~ 0 Code – S : severity bit – Facility : FACILITY_NULL, FACILITY_ITF, FACILITY_DISPATCH, FACILITY_RPC, FACILITY_STORAGE – Code : Error Code ISLab ICE HUFS Component Programming 22
HRESULT type (cont’d) • 몇 몇 유명한 HRESULT 값들 • • S_OK(==0), NOERROR(==S_OK) : 성공(true) S_FALSE(==1) : 성공 (false) E_UNEXPECTED : 예상치 못한 실패 E_NOTIMPL : 구현되지 않았음 E_NOINTERFACE : 그런 인터페이스가 없음. E_OUTOFMEMORY : 메모리 부족 E_FAIL : 실패 ISLab ICE HUFS Component Programming 23
GUID/UUID (cont’d) • GUID/UUID – Globally Unique IDentifier – Universal Unique IDentifier (==GUID) • 128 비트 구조체 • Uuid. Create() 로 생성됨 • 함수를 실행할 때 마다 고유한 UUID를 생성하는 것을 보 장 ISLab ICE HUFS Component Programming 26
GUID/UUID (cont’d) • 실제 모습 typedef struct _GUID { DWORD Data 1; WORDData 2; WORDData 3; BYTE Data 4[8]; } GUID; ISLab ICE HUFS Component Programming 27
GUID/UUID (cont’d) • 표기 방법 – 레지스트리 형식 • {2 B 836510 -FCBE-11 d 2 -98 A 8 -00 AA 006 d. EEA 4} • {0000 -0000 -C 000 -0000046} – 구조체 형식 • extern “C” const GUID IID_My. Interface = { 0 x 2 b 836510, 0 xfcbe, 0 x 11 d 2, { 0 x 98, 0 xa 8, 0 x 00, 0 xaa, 0 x 00, 0 x 6 d, 0 xee, 0 xa 4 } }; • GUIDGEN. EXE / UUIDGEN. EXE ISLab ICE HUFS Component Programming 28
GUID/UUID (cont’d) • 동의어들 typedef GUID UUID; #define uuid_t UUID typedef GUID IID; // interface id typedef GUID CLSID; // class id typedef const GUID& REFGUID; typedef const CLSID& REFCLSID; typedef const IID& REFIID; • 비교 함수 – Is. Equal. GUID, Is. Equal. IID, Is. Equal. CLSID ISLab ICE HUFS Component Programming 29
IUnknown 인터페이스 struct IUnknown { HRESULT __stdcall Query. Interface(REFIID iid, void** ppv. Object ) = 0; ULONG __stdcall Add. Ref(void) = 0; ULONG __stdcall Release(void) = 0; }; ISLab ICE HUFS Component Programming 30
ICar. Control COM버전 #define STDMETHOD(FUNC) virtual HRESULT __stdcall FUNC #define STDMETHOD_(RET, FUNC) virtual RET __stdcall FUNC struct ICar. Control : public IUnknown { STDMETHOD(Rotate. Handle)( long n. Angle ) = 0; STDMETHOD(Set. Gear)( long n. Level ) = 0; STDMETHOD(Accelerate)( long n. Rpm ) = 0; STDMETHOD(Break)() = 0; STDMETHOD_(long, Get. Speed)() = 0; }; ※ STDMETHOD 는 objbase. h 에 진짜로 정의되어 있음 ISLab ICE HUFS Component Programming 31
Driving the Tico IUnknown* p. Unk = ? ? ? ; HRESULT h. Res; IRadio* p. Radio = 0; ICar. Control* p. Control = 0; // 어떤 방법을 써서 // p. Unk가 Tico객체를 참조 // 하게 되었다고 가정함 // (그 방법은 나중에 나옴) h. Res = p. Unk->Query. Interface(IID_IRadio , (void**)&p. Radio ); if ( !SUCCEEDED( h. Res ) ) return h. Res; h. Res = p. Unk->Query. Interface(IID_ICar. Control , (void**)&p. Control ); if ( !SUCCEEDED( h. Res ) ) return h. Res; p. Radio->Tune( 91. 9 ); p. Radio->Set. Volumn( 10 ); p. Control->Set. Gear( 1 ); p. Control->Accelerate( 3000 ); p. Control->Set. Gear( 2 ); p. Control->Rotate. Handle( 10 ); : p. Control->Release(); p. Radio->Release(); p. Unk->Release(); // 이것이 Tico를 참조하던 마지막 // 참조였다면 Tico는 delete됨 ISLab ICE HUFS Component Programming 32
ISLab ICE HUFS 2. COM 객체의 생성과 사용 Component Programming
COM 객체가 있는 곳 Marshalling Application EXE Remote Server Marshalling DLL EXE In-process Server Local Server Process A Process B Host A Component Programming Host B ISLab ICE HUFS 36
Local Server • Local Server – – COM 객체를 EXE(실행파일)이 제공 RPC (Remote Procedure Call) 을 통해서 통신해야 함 속도가 현저히 떨어짐 독립적으로 실행할 수 있다는 장점 ISLab ICE HUFS Component Programming 39
Local Server (cont’d) • IDL 파일 예제 import "oaidl. idl"; import "ocidl. idl"; [ object, uuid(B 128513 B-FD 1 C-11 D 2 -98 A 9 -0000212035 B 8), helpstring("ICar. Control 인터페이스"), pointer_default(unique) ] ISLab ICE HUFS Component Programming 41
Local Server (cont’d) interface ICar. Control : IUnknown { [helpstring("Rotate. Handle 메쏘드")] HRESULT Rotate. Handle([in] long n. Angle); [helpstring("Set. Gear 메쏘드")] HRESULT Set. Gear([in] long n. Level); [helpstring("Accelerate 메쏘드")] HRESULT Accelerate([in] long n. Rpm); }; ISLab ICE HUFS Component Programming 42
Remote Server • Remote Server – COM 객체를 제공하는 서버가 리모트 호스트에 존재 – 그 외에는 Local Server와 같음 • RPC – Network 을 통해서 이루어 짐 • DCOM (Distributed COM) – Remote Server를 통한 분산 COM 을 뜻함 ISLab ICE HUFS Component Programming 43
객체를 생성하는 객체 • IClass. Factory 인터페이스 – 이 인터페이스를 제공하는 객체는 새로운 객체를 생성할 수 있는 능력을 가짐 – 이름과 달리 Class가 아닌 Object를 생성 HRESULT Create. Instance( IUnknown* p. Unk. Outer, REFIID riid, void** ppv. Object ); ISLab ICE HUFS Component Programming 44
COM 객체 생성 h. Res = Co. Initialize( NULL ); h. Res = Co. Create. Instance( clsid, NULL, CLSCTX_ALL, IID_IUnknown, (void**)p. Unk ); p. Unk->Release(); h. Res = Co. Uninitialize(); • CLSCTX : CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER ISLab ICE HUFS Component Programming 45
COM 객체 생성 (cont’d) ISLab ICE HUFS Component Programming 46
COM 객체 생성 (cont’d) ISLab ICE HUFS Component Programming 47
COM 객체 생성 (cont’d) • 객체 생성 개요 – COM은 CLSID에 해당하는 클래스 객체에서 Query. Interface로 IClass. Factory 인터페이스를 얻고, IClass. Factory: : Create. Instance 함수로 객체를 생성 – 이후에 IClass. Factory를 Release 함 – IClass. Factory 자체를 얻고 싶으면 Co. Get. Class. Object 함수 사용 ISLab ICE HUFS Component Programming 48
Prog. ID ISLab ICE HUFS Component Programming 50
참고 : COM 에서 사용되는 스트링 • UNICODE – – – 대부분의 언어에서 쓰이는 문자를 2바이트로 인코딩 wchar_t, WCHAR, OLECHAR L”MSCAL. Calendar” Multi. Byte. To. Wide. Char, Wide. Char. To. Multi. Byte OLE 2 A, OLE 2 T … (string conversion macros) LPCTSTR ISLab ICE HUFS Component Programming 52
- Slides: 52