Lưu ý
Cần có ủy quyền mới truy nhập được vào trang này. Bạn có thể thử đăng nhập hoặc thay đổi thư mục.
Cần có ủy quyền mới truy nhập được vào trang này. Bạn có thể thử thay đổi thư mục.
Any process that uses COM must both initialize and uninitialize the COM library. In addition to being a specification, COM also implements some important services in this library. Provided as a set of DLLs and EXEs (primarily Ole32.dll and Rpcss.exe) in Microsoft Windows, the COM library includes the following:
A small number of fundamental functions that facilitate the creation of COM applications, both client and server. For clients, COM supplies basic functions for creating objects. For servers, COM supplies the means of exposing their objects.
Implementation-locator services through which COM determines, from a unique class identifier (CLSID), which server implements that class and where that server is located. This service includes support for a level of indirection, usually a system registry, between the identity of an object class and the packaging of the implementation so that clients are independent of the packaging, which can change in the future.
Transparent remote procedure calls when an object is running in a local or remote server.
A standard mechanism to allow an application to control how memory is allocated within its process, particularly memory that needs to be passed between cooperating objects so that it can be freed properly.
To use basic COM services, all COM threads of execution in clients and out-of-process servers must call either the CoInitialize or the CoInitializeEx function before calling any other COM function except memory allocation calls. CoInitializeEx replaces the other function, adding a parameter that allows you to specify the threading model of the thread: either apartment-threaded or free-threaded. A call to CoInitialize simply sets the threading model to apartment-threaded.
OLE compound document applications call the OleInitialize function, which calls CoInitializeEx and also does some initialization required for compound documents. Therefore, threads that call OleInitialize cannot be free-threaded. For information on threading in clients and servers, see Processes, Threads, and Apartments.
In-process servers do not call the initialization functions because they are being loaded into a process that has already done so. As a result, in-process servers must set their threading model in the registry under the InprocServer32 key. For detailed information on threading issues in in-process servers, see In-Process Server Threading Issues.
It is also important to uninitialize the library. For each call to CoInitialize or CoInitializeEx, there must be a corresponding call to CoUninitialize. For each call to OleInitialize, there must be a corresponding call to OleUninitialize.
In-process servers can assume that the process they are being loaded into has already performed these steps.
Important
Every thread that uses COM must call CoInitializeEx before calling any other COM function. This is the most common COM initialization mistake — calling CoCreateInstance or other COM APIs on a thread that has not been initialized will fail with CO_E_NOTINITIALIZED (0x800401F0).
Tip
Recommended pattern — use an RAII guard to ensure uninitialization:
#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 ...
If wil is not available, call CoUninitialize() manually — each successful CoInitializeEx call must be paired with exactly one CoUninitialize call:
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) return hr;
// ... use COM ...
CoUninitialize();
Important
Common mistakes:
- Calling COM functions without initializing COM on the current thread.
- Mismatching
CoInitializeEx/CoUninitializecalls (each successful init needs exactly one uninit). - Mixing apartment models on the same thread (calling
CoInitializeExwith a different model than a previous successful call returnsRPC_E_CHANGED_MODE).
Related topics