com初始化线程问题

Com简介

Com接口本质是原始Windows API的封装,使用Com的应用程序相当于是一个RPC客户端,去跟Com的server去交互。

STA和MTA

使用Com接口首先就是要初始化,就需要使用相关的两个接口

1
2
CoInitialize();
CoInitializeEx();//从字面意思就可以看出这是上个接口的扩展,支持更多的参数

CoInitializeEx第二个参数,是一个枚举值,支持以下几种类型:

1
2
3
4
5
6
7
8
9
10
11
typedef enum tagCOINIT
{
COINIT_APARTMENTTHREADED = 0x2, // Apartment model

#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
// These constants are only valid on Windows NT 4.0
COINIT_MULTITHREADED = COINITBASE_MULTITHREADED,
COINIT_DISABLE_OLE1DDE = 0x4, // Don't use DDE for Ole1 support.
COINIT_SPEED_OVER_MEMORY = 0x8, // Trade memory for speed.
#endif // DCOM
} COINIT;

其中COINIT_APARTMENTTHREADED表示单线程初始化(STA),和直接用CoInitialize(0)是一样的。COINIT_MULTITHREADED表示多线程初始化(MTA)。这两种模式的区别在于,STA模式只针对当前调用线程,也就是在哪个线程初始化,就只能在哪个线程调用Com接口。如果在别的线程调用Com接口,就会抛出未初始化的错误码(CO_E_NOTINITIALIZED)。

如果使用MTA模式,只需要在一个线程初始化,通常是主线程,就可以在其他线程调用Com接口,通过windows消息将当前线程的操作转发到初始化线程,进行排队处理。这种情况下需要应用程序自己保证线程安全。

有初始化就有卸载释放资源,只需要调用CoUninitialize()即可。STA模式在哪个线程初始化就在哪个线程结束时卸载。而MTA只需要在一个线程初始化,在该线程结束时卸载即可。


com初始化线程问题
http://yoursite.com/2021/04/03/com初始化线程问题/
作者
还在输入
发布于
2021年4月3日
许可协议