1 CoInitialize
CoInitialize是在当前线程初始化Com组件的函数,并且初始化为STA模式(单线程模式)
CoInitialize(
LPVOID pvReserved // 系统 保留的参数,必须传入 NULL.
);
特点:
- 设置后, 线程就进入了单线程单元, 在这个单元里只能住一个线程. 该线程上创建的Com对象方法被另一个线程调用时, Com运行库会把这个方法编到一个队列里, windows消息会被放进线程消息队列
所有Com方法调用的执行过程 都被放到 创建Com对象的那个线程
2 CoInitializeEx
CoInitializeEx初始化当前线程Com组件, 并且初始化为MTA模式(多线程模式)
CoInitialize(
LPVOID pvReserved, // 系统 保留的参数,必须传入 NULL.
DWORD dwCoInit // 指明基于当前线程的并发模式, 一般传0, 即COINIT_MULTITHREADED
);
dwCoInit:
COINIT_MULTITHREADED = 0, // 允许多线程调用, 但每个Com方法调用的执行过程 被放到 各自的调用线程中
- COINIT_APARTMENTTHREADED = 2, // 允许多线程调用,但所有Com方法调用的执行过程 都被放到 创建Com对象的那个线程
上面这两种最常用, 但两者不能组合使用
- COINIT_DISABLE_OLE1DDE = 4, // 禁用DDE对OLE1的支持
COINIT_SPEED_OVER_MEMORY = 8, // 增加内存使用来使性能上升
3 两个函数返回值的说明
HRESULT hr = CoInitialize(NULL);
// hr == S_OK COM库初始化成功
// hr == S_FALSE 当前线程上,COM库已经被初始化
// hr == RPC_E_CHANGED_MODE COM库已经被初始化且传入参数设置的并发模式和本次不同
4 注意事项
(1) 要在一个线程上合理关闭com库,在线程函数尾部还要有CoUninitialize()
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// ...
CoUninitialize();
(2) 在MFC程序中初始化Com库, 有两种方法
CoInitialize(0);
- CoInitializeEx(0, COINIT_APARTMENTTHREADED);
原因: MFC使用TLS来维护一些进程线程状态信息,这会和自由线程模型的组件发生冲突。
(3) Qt主线程不用执行COM初始化,因为已经自动初始化为STA