CoInitializeEx 与CoInitialize的区别

CoInitialize、CoInitializeEx都是windows的API,主要是告诉windows以什么方式为程序创建COM对象,原因是程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
 
     有哪些方式呢?单线程和多线程。
      CoInitialize指明以单线程方式创建。
      CoInitializeEx可以指定COINIT_MULTITHREADED以多线程方式创建。
      创建单线程方式的COM服务器时不用考虑串行化问题,多线程COM服务器就要考虑。
      在使用中,使用CoInitialize创建可使对象直接与线程连接,得到最高的性能。创建多线程对象可以直接接收所有线程的调用,不必像单线程那样需要消息排队,但却需要COM创建线程间汇集代理,这样访问效率不高。


注:新的应用程序应该调用CoInitializeEx而不是CoInitialize,一般是在 Dll 中使用 COM 才会需要使用的。
 

-----------------------------

 
  对于每个使用com库的线程,CoInitializeEx 至少必须调用一次,通常也只调用一次。只要传递相同的并发标志参数,同一个线程多次调用CoInitializeEx也是允许的,但是后面的有效调用返回S_FLASE。 要在一个线程上合理关闭com库,每一次成功调用CoInitialize或者CoInitializeEx (包括任何返回S_FALSE的调用),都必须对应调用一次CoUninitialize。


  注意:要使用CoInitializeEx必须在代码开始包含#define _WIN32_DCOM预编译命令一 个线程,除了调用CoGetMalloc函数和其它内存分配(CoTaskMemAlloc, CoTaskMemFree,CoTaskMemReAlloc, and the IMalloc methods on the task allocationsupplied byCoGetMalloc),在调用任何其它com库函数前必须调用CoInitializeEx或者CoInitialize,,否则com库函数会返回CO_E_NOTINITIALIZED。


  一旦线程并发模式被设置,就无法再改变。在线程上再次调用CoInitializeEx,传递与之前初始化调用不同的并发机制参数,函数将返回RPC_E_CHANGED_MODE 错误值。


  如果并发模式没有设置dwCoInit参数,默认值取COINIT_MULTITHREADED。


  在单线程单元创建的对象,只能从他们的单元线程中接收方法调用,因此调用是序列化的,而且只能通过消息队列(当调用win32函数PeekMessage或SendMessage)到达。


  在多线程单元创建的com对象,必须能够在任何时候接收来自其它线程的方法调用。在多线程对象编码中,你可能会使用win32同步机制,譬如临界区、信号量、互斥等来实现并发控制,帮助保护对象数据。


  当运行在中立线程单元的对象被STA或MTA线程调用时,该线程转为NTA。如果这个线程在后面调用CoInitializeEx,调用失败,返回RPC_E_CHANGED_MODE错误代码。


  CoInitializeEx 提供与CoInitialize相同的功能,而且也提供参数显式指定线程的并发模式。CoInitalize当前实现是通过调用CoInitializeEx,并指定并发模式为单线程单元。今天的应用开发应该调用CoinitializeEx,而不是CoInitialize。


  因为OLE技术不是线程安全的,函数OleInitialize调用用CoInitializeEx,并传入参数COINIT_APARTMENTTHREADED标志。因此,初始化为多线程对象并发的单元无法使用OleInitialze激活的特性。


  因为没有办法控制进程内服务加载与卸载的顺序,因此不要在DllMain函数内调用CoInitialize,CoInitializeEx, 或 CoUninitialize。


你可能感兴趣的:(C/C++)