任何 Windows 程序在使用 COM 组件 前都必须调用 CoInitializeEx 函数初始化。使用 COM 接口 的每个线程都需要执行这个初始化步骤, CoInitializeEx 函数的声明如下:

HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);

第一个参数是保留参数,必须传 NULL。第二个参数指定你程序中使用的线程模型。COM 组件支持两种不同的线程模型:单元线程(apartment threaded)和 多线程(multithreaded)。如果你是用单元线程,则需要确保下面两点:

  • 你不能在多线程之间共享 COM 接口,只能在线程内部独自访问。

  • 线程内部会有一个 Windows 消息循环。

如果上面两种条件无法做到,就只能使用多线程模型。通过下面两个参数指定使用的线程模型:

标识 描述
COINIT_APARTMENTTHREADED Apartment threaded.
COINIT_MULTITHREADED Multithreaded.

上述两个标记你必须选择其中之一。一般情况下,创建窗口的线程使用 COINIT_APARTMENTTHREADED 标记,其他线程使用 COINIT_MULTITHREADED 标记。然而有一些特殊情况,需要根据具体的 COM 组件的帮助文档来确定使用哪种标记。

其实,在指定单元线程之后,仍然可以跨线程使用 COM 接口,具体使用一种叫做 marshaling 的技术实现。重要的是如果使用单元线程,你不可以简单的在线程之前拷贝接口指针,关于更多的信息可以参考 MSDN。

除了上面两个标记为,设置 COINIT_DISABLE_OLE1DDE 标记是一个不错的主意。设置该标记为可以避免一些对象链接嵌入( Object Linking and Embedding)1.0 的开销,这是一种过时的技术。下面是初始化 COM 组件 的代码:

HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

CoInitializeEx 返回一个 HRESULT 类型的结果,该结果存储着一个错误码,代表着函数执行的结果。

如果调用 CoInitializeEx 成功初始化后,你必须在线程退出前调用 CoUninitialize 函数。这个函数没有任何参数和返回值。

CoUninitialize();
求关注