COM 컴포넌트 모델의 인터페이스와 Windows 상호운용 구조

COM의 바이너리 인터페이스, IUnknown 참조 카운팅, GUID, DCOM과 COM+의 동작 구조를 정리한다.

2026-08-14 · 최초 발행 2026-01-12

바이너리 인터페이스로 컴포넌트를 연결하는 COM

COM(Component Object Model)은 Microsoft가 만든 컴포넌트 기반 소프트웨어 아키텍처다. 핵심은 소스코드가 아니라 바이너리 수준의 인터페이스다. 따라서 C++, VB, Delphi처럼 서로 다른 언어로 만든 컴포넌트도 약속된 인터페이스를 통해 통신하고 재사용할 수 있다.

COM은 인터페이스 중심으로 동작하며, 컴포넌트가 어느 위치에서 실행되는지도 호출자에게는 같은 인터페이스로 드러난다.

특성 내용
언어 독립성 C++, VB, Delphi 등 다양한 언어 지원
위치 투명성 인프로세스, 로컬, 원격에서 동일한 인터페이스 사용
버전 호환성 인터페이스 불변성 원칙
바이너리 표준 소스코드 없이 컴포넌트 재사용

런타임과 클래스 팩토리로 객체를 찾는 구조

클라이언트는 COM 런타임을 거쳐 클래스 팩토리에 객체 생성을 요청한다. 생성된 COM 객체는 IUnknown과 필요한 개별 인터페이스를 제공한다.

서버 프로세스COM Runtime클라이언트Client ApplicationService Control ManagerRPC ChannelClass FactoryCOM ObjectIUnknownInterface AInterface B

COM 객체와 주변 구성요소는 다음 역할로 나뉜다.

구성요소 역할
COM Object 인터페이스를 구현하는 객체
Interface 메서드 집합 정의
Class Factory 객체 생성 팩토리
SCM 서비스 제어 관리자
Registry 컴포넌트 등록 정보
Type Library 인터페이스 메타데이터

IUnknown이 맡는 인터페이스 조회와 수명 관리

모든 COM 인터페이스는 IUnknown을 기반으로 한다. 모든 COM 객체가 구현해야 하며, QueryInterface, AddRef, Release를 통해 다른 인터페이스를 얻고 객체의 참조 수를 관리한다.

IUnknownQueryInterface인터페이스 조회AddRef참조 카운트 증가Release참조 카운트 감소
메서드 기능 반환
QueryInterface 다른 인터페이스 포인터 획득 HRESULT
AddRef 참조 카운트 1 증가 ULONG
Release 참조 카운트 1 감소 ULONG

참조 카운팅은 객체가 더 이상 필요하지 않은 시점을 결정한다. 객체를 생성한 뒤 인터페이스를 추가로 요청하면 참조 수가 증가하고, 호출자가 Release를 수행하면서 참조가 모두 사라지면 객체가 소멸한다.

COM ObjectClientCOM ObjectClientRefCount = 1RefCount = 2RefCount = 1RefCount = 0, 객체 소멸CoCreateInstanceQueryInterfaceReleaseRelease

GUID로 클래스와 인터페이스를 구분한다

COM은 전역적으로 고유한 식별자인 GUID를 사용한다. GUID는 128비트 식별자이며 {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 형식을 따른다. 알고리즘에 기반해 고유성을 보장한다.

COM 환경에서는 식별 대상에 따라 서로 다른 GUID 유형을 사용한다.

식별자 용도 예시
CLSID 클래스 식별 CLSID_Application
IID 인터페이스 식별 IID_IUnknown
LIBID 타입 라이브러리 식별 LIBID_Office
CATID 컴포넌트 카테고리 CATID_Control

실행 위치에 따라 달라지는 COM 서버

COM 서버는 클라이언트와 같은 프로세스에 로드될 수도 있고, 별도 프로세스나 원격 컴퓨터에서 실행될 수도 있다.

In-Process Server (DLL)

DLL 형태의 서버는 클라이언트 프로세스 안에 로드된다. 같은 주소 공간을 사용하므로 가장 빠르지만 격리는 제공하지 않는다.

클라이언트 프로세스ClientCOM DLLIn-Process Server

Local Server (EXE)

EXE 형태의 로컬 서버는 별도 프로세스로 실행된다. 클라이언트는 프록시를 거쳐 LPC(Local Procedure Call)로 서버의 스텁과 통신하며, 프로세스 수준의 격리를 얻는다.

서버 프로세스클라이언트 프로세스LPCClientProxyStubCOM EXELocal Server

Remote Server (DCOM)

원격 서버는 다른 컴퓨터에서 실행되는 COM 서버다. 통신에는 네트워크를 통한 RPC를 사용하며, 이 분산 통신 모델을 DCOM(Distributed COM)이라고 한다.

IDL에서 계약을 정의하고 MIDL로 산출물을 만든다

COM 인터페이스는 IDL(Interface Definition Language)로 정의할 수 있다. 다음 예시는 IUnknown을 상속한 계산기 인터페이스다.

[
    object,
    uuid(12345678-1234-1234-1234-123456789ABC),
    pointer_default(unique)
]
interface ICalculator : IUnknown
{
    HRESULT Add([in] int a, [in] int b, [out, retval] int* result);
    HRESULT Subtract([in] int a, [in] int b, [out, retval] int* result);
    HRESULT Multiply([in] int a, [in] int b, [out, retval] int* result);
    HRESULT Divide([in] int a, [in] int b, [out, retval] int* result);
}

MIDL 컴파일러는 IDL 정의를 바탕으로 헤더 파일, 타입 라이브러리, 프록시와 스텁 코드를 생성한다.

IDL 파일MIDL 컴파일러헤더 파일 (.h)타입 라이브러리 (.tlb)프록시/스텁 코드

COM 위에서 확장된 기술

OLE(Object Linking and Embedding)는 복합 문서를 위한 기술이다. 문서 안에 객체를 삽입하거나 연결할 수 있으며, Word 문서에 Excel 차트를 삽입하는 용도로 사용된다.

ActiveX는 웹 기반 COM 컨트롤이다. 브라우저 플러그인과 리치 클라이언트에 사용되며, 코드 서명이 필요하다.

Automation은 IDispatch를 통해 스크립팅 언어가 COM 객체를 사용할 수 있도록 한다. 런타임 바인딩을 특징으로 하며 VBScript와 JavaScript에서 COM 호출에 사용된다.

IDispatchQueryInterfaceGetTypeInfoCountGetTypeInfoGetIDsOfNamesInvoke

네트워크 너머의 COM, DCOM

DCOM은 네트워크 기반의 분산 COM이며 TCP/IP 위에서 RPC를 사용한다. 로컬 COM과 같은 인터페이스로 원격 객체에 접근할 수 있다는 점이 특징이다.

서버 머신클라이언트 머신Network RPCClientProxyORPCORPCStubCOM Server

DCOM 보안은 인증, 접근 제어, 암호화, 위장으로 구분해 볼 수 있다.

수준 설명
인증 NTLM, Kerberos
권한 ACL 기반 접근 제어
암호화 패킷 암호화 옵션
위장 클라이언트 컨텍스트

COM+가 더한 엔터프라이즈 서비스

COM+는 COM에 엔터프라이즈 서비스를 추가한 기술이며, 이전 이름은 MTS(Microsoft Transaction Server)다. 관리는 Component Services MMC에서 수행한다.

COM+트랜잭션관리객체 풀링JIT 활성화역할 기반보안 컴포넌트이벤트서비스
서비스 기능
분산 트랜잭션 DTC를 통한 2PC 트랜잭션
객체 풀링 객체 재사용으로 성능 향상
JIT 활성화 필요 시 객체 활성화
역할 기반 보안 선언적 보안 설정

.NET 환경에서 이어지는 COM 상호운용

COM과 .NET은 메타데이터, 배포, 버전 관리, 메모리 관리 방식이 다르다. .NET은 COM Interop을 통해 기존 COM 구성요소와 연결할 수 있다.

항목 COM .NET
메타데이터 Type Library Assembly Manifest
배포 레지스트리 등록 XCOPY/GAC
버전 관리 복잡 (DLL Hell) Side-by-Side
메모리 관리 참조 카운팅 가비지 컬렉션
상호운용 - COM Interop

.NET에서 COM 객체를 사용할 때는 RCW(Runtime Callable Wrapper)를 사용하고, COM에서 .NET을 사용할 때는 CCW(COM Callable Wrapper)를 사용한다.

COM은 IUnknown 기반의 인터페이스 조회와 참조 카운팅을 통해 언어 독립적인 컴포넌트 재사용을 제공한다. OLE, ActiveX, DCOM, COM+으로 확장된 이 구조는 .NET으로 대체되는 추세에도 Windows 운영체제와 Office 등 Microsoft 제품의 기반으로 남아 있다.

COMWindows컴포넌트 모델IUnknownDCOM