COM 初始化,说简单很简单,说复杂,有些时候还真不简单。
首先,CoInitialize(NULL)和CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);是一样的。我们尽可能使用CoInitializeEx来初始化COM比较好。
STA套间
调用CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);,那么COM系统就会为calling thread创建一个单线程套间。
如果再调用一次CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);那么CoInitializeEx()还是会成功,但是返回一个S_FALSE。也就是说多次初始化COM是可以的。
但是如果在初始化成单线程套间后,再去尝试初始化多线程套间,那就会失败,返回值会提示“不可以修改套间类型”啥的。
每一次成功的CoInitializeEx都最后有一个对应的CoUninitialize(),这样就比较优雅。当然如果不CoUninitialize,通常问题也不大。
一个进程里面可以有多个STA套间,每个STA套间有且仅有一个线程。一个STA套间里面可以有多个STA对象。
MTA套间
使用CoInitializeEx(NULL, COINIT_MULTITHREADED);来创建一个MTA套间。一个进程里面只能有一个MTA套间。
比如我们在主线程里面创建了MTA套间,那么主线程就属于MTA套间。所有其他辅助线程,如果自己没有初始化COM,那么默认就属于MTA套间。
如果辅助线程自己初始化COM,就看情况而定。总体来说,当主线程初始化成MTA后,辅助线程有三种情况:
1. 辅助线程不初始化COM,那么就默认属于MTA套间
2. 辅助线程初始化成MTA套间,那么还是属于MTA套间
3. 辅助线程初始化成STA套间,那么辅助线程就属于STA套间。
一个进程只有1个MTA套间,但是可以有多个STA套间。每个MTA套间里面可以有多个线程。