任何一个使用COM组件的windows程序在初始化COM库的时候都要调用CoInitializeEx函数,每一个使用COM接口的线程必须单独调用这个函数。下面是这个函数的声明:
HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
第一个参数是保留参数,为空。第二个参数规定了将使用的线程模型。COM接口支持两种不同的线程模型:单线程和多线程。一旦指定了单线程模型,就以意味着:
1.你将通过单线程来访问每一个COM对象;在不同的线程之间不可以共享COM接口指针;
2.线程将会有一个消息队列。
如果上述任何一条不满足的话,就需要指定multithreaded模型。下表为两种模型的标识符。
Flag Description
COINIT_APARTMENTTHREADED Apartment threaded.
COINIT_MULTITHREADED Multithreaded.
你必须设置清楚上述标记位。通常来讲,创建窗口的线程应该使用COINIT_APARTMENTTHREADED ,其它线程应该使用COINIT_MULTITHREADED。然而,一些COM组件需要特定的线程模型,在MSDN文档中会对这种情况有所介绍。
实际上,即使你指定了apartment线程,通过使用marshaling技术,线程之间共享接口也是有可能的;但是,你不能够将一个接口指针复制给另外一个线程。下面给出了
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
这个函数返回类型HRESULT包含了正确或者错误的代码。下文中我将介绍错误处理。每一次成功调用CoInitializeEx之后,你必须调用CoUninitialize函数,该函数定义如下
CoUninitialize();
Note Actually, even if you specify apartment threading, it is still possible to share interfaces between threads, by using a technique called marshaling. Marshaling is beyond the scope of this module. The important point is that with apartment threading, you must never simply copy an interface pointer to another thread. For more information about the COM threading models, see Processes, Threads, and Apartments and Understanding and Using COM Threading Models.
In addition to the flags already mentioned, it is a good idea to set the COINIT_DISABLE_OLE1DDE flag in the dwCoInit parameter. Setting this flag avoids some overhead associated with Object Linking and Embedding (OLE) 1.0, an obsolete technology.