您的位置:首页 > 其它

CoInitializeEx 与CoInitialize的区别

2016-02-26 23:52 246 查看
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: