In this article, I'll not talk about how it works about the COM's apartment model, but the coding practice.
CoInitializeEx() provides the same functionality as CoInitialize() except it provides a parameter to specify the thread's apartment model. So, MSDN recommands us to call CoInitializeEx() instead of CoInitialize().
For using CoInitializeEx(), we also need to follow the same rules as CoInitialize(), I mentioned in the previous article.
The following examples explain how to use CoInitializeEx() and CoUninitialize():
Example #1: CoInitializeEx() will return S_FALSE if the COM library was loaded.
void main()
{
HRESULT hr = E_FAIL;
// The first call
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK
// The second call
hr = CoInitialize(NULL); // hr = S_FALSE, CoInitialize(NULL) = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)
// ... skip ...
// For the second call
CoUninitialize();
// For the first call
CoUninitialize(); // COM library will be unloaded
}
Example #2: CoInitializeEx() will return RPC_E_CHANGED_MODE if a previous call to CoInitializeEx() specified a different apartment model
void main()
{
HRESULT hr = E_FAIL;
// The first call
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK
// The second call
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // hr = RPC_E_CHANGED_MODE, the thread's apartment model is still the single thread apartment.
// ... skip ...
// NOTE: We do not need to call CoUninitialize() if the corresponding call made by CoInitializeEx() returns error.
// For the first call
CoUninitialize(); // COM library will be unloaded
}