COM을 사용하는 모든 프로세스는 COM 라이브러리를 초기화하고 초기화하지 않아야 합니다. COM은 사양 외에도 이 라이브러리에서 몇 가지 중요한 서비스를 구현합니다. Microsoft Windows에서 DLL 및 EXE(주로 Ole32.dll 및 Rpcss.exe) 집합으로 제공되는 COM 라이브러리에는 다음이 포함됩니다.
클라이언트와 서버 모두에서 COM 애플리케이션을 쉽게 만들 수 있는 몇 가지 기본 함수입니다. 클라이언트의 경우 COM은 개체를 만들기 위한 기본 함수를 제공합니다. 서버의 경우 COM은 개체를 노출하는 수단을 제공합니다.
COM이 CLSID(고유 클래스 식별자)를 통해 특정 클래스를 구현하는 서버와 그 서버의 위치를 확인하는 구현 로케이터 서비스를 제공합니다. 이 서비스에는 개체 클래스의 ID와 구현 패키징 간의 간접 참조 수준(일반적으로 시스템 레지스트리)에 대한 지원이 포함되므로 클라이언트가 패키징과 독립적이므로 나중에 변경될 수 있습니다.
개체가 로컬 또는 원격 서버에서 실행 중일 때 투명한 원격 프로시저가 호출됩니다.
애플리케이션이 프로세스 내에서 메모리를 할당하는 방법, 특히 제대로 해제할 수 있도록 협력 개체 간에 전달해야 하는 메모리를 제어할 수 있도록 하는 표준 메커니즘입니다.
기본 COM 서비스를 사용하려면 메모리 할당 호출을 제외한 다른 COM 함수를 호출하기 전에 클라이언트 및 out-of-process 서버의 모든 COM 실행 스레드는 CoInitialize 또는 CoInitializeEx 함수를 호출해야 합니다. CoInitializeEx 다른 함수를 대체하여 스레드의 스레딩 모델(아파트 스레드 또는 자유 스레드)을 지정할 수 있는 매개 변수를 추가합니다. CoInitialize 호출하면 스레딩 모델이 아파트 스레드로 설정됩니다.
OLE 복합 문서 애플리케이션은 CoInitializeEx 호출하고 복합 문서에 필요한 일부 초기화를 수행하는 OleInitialize 함수를 호출합니다. 따라서 OleInitialize 호출하는 스레드는 자유 스레드가 될 수 없습니다. 클라이언트 및 서버의 스레딩에 대한 자세한 내용은 프로세스, 스레드 및 아파트참조하세요.
In-process 서버는 이미 수행된 프로세스에 로드되고 있으므로 초기화 함수를 호출하지 않습니다. 따라서 in-process 서버는 InprocServer32 키 아래 레지스트리에서 스레딩 모델을 설정해야 합니다. in-process 서버의 스레드 처리 문제에 대한 자세한 내용은 In-Process 서버 스레드 처리 문제참조하세요.
라이브러리를 초기화하지 않는 것도 중요합니다. 각각의 CoInitialize 또는 CoInitializeEx호출마다, 이에 대응하는 CoUninitialize호출이 있어야 합니다. OleInitialize를 호출할 때마다, OleUninitialize를 호출해야 합니다.
In-process 서버는 로드되는 프로세스가 이미 이러한 단계를 수행했다고 가정할 수 있습니다.
Important
COM을 사용하는 모든 스레드는 다른 COM 함수를 호출하기 전에 호출 CoInitializeEx 해야 합니다. 이는 가장 일반적인 COM 초기화 실수입니다. 초기화되지 않은 스레드에서 호출하거나 다른 COM API를 호출 CoCreateInstance 하면 CO_E_NOTINITIALIZED 실패합니다(0x800401F0).
Tip
권장 패턴 - RAII 가드를 사용하여 초기화 해제를 보장합니다.
#include <wil/com.h> // Windows Implementation Libraries
// wil::unique_couninitialize_call calls CoUninitialize automatically on scope exit
auto comInit = wil::CoInitializeEx(COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
// ... use COM — CoUninitialize is called when comInit goes out of scope,
// even if an exception is thrown ...
wil을 사용할 수 없는 경우 수동으로 호출 CoUninitialize() 합니다. 성공한 CoInitializeEx 각 호출은 정확히 하나의 CoUninitialize 호출과 페어링되어야 합니다.
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) return hr;
// ... use COM ...
CoUninitialize();
Important
일반적인 실수:
- 현재 스레드에서 COM을 초기화하지 않고 COM 함수를 호출합니다.
- 일치하지 않는
CoInitializeEx/CoUninitialize호출(성공한 각 init에는 정확히 하나의 uninit 호출이 필요함). - 동일한 스레드에서 아파트 모델을 혼용하는 경우(이전에 성공한 호출과 다른 모델로
CoInitializeEx를 호출하면RPC_E_CHANGED_MODE가 반환됨).
관련 항목