调用任何COM组件之前,你必须首先初始化COM套件环境,即调用CoInitialize或CoInitializeEx。COM套件环境在线程的生存周期内有效,线程退出前需要调用CoUninitialize释放COM套件。

所谓COM套件,实际上是微软为了方便大家理解而起的一个名字,不过个人认为改名词很难理解。COM套件只指COM组件运行时的环境,其中包括COM组件的数据、变量、线程调度方式。

COM套件分为两种模式,单线程套件(STA)和多线程套件(MTA)。不要单从字面上理解,例如:STA并非只能用于单线程的程序,多线程程序依然可以使用。下面列出两种套件模式的区别。

套件类型

说明

性能

兼容性

常见错误
STA

单线程套间,一个进程内所有COM组件都运行在主STA中,主STA就是第一个调用CoInitialize函数的线程。

也就是说,即使你拥有多线程程序,但在不通线程同时操作COM组件的时候,COM组件会通过Windows消息、Event同步对象之类的机制把调用转换到主STA执行,而主STA通常对应应用程序的主线程。这样对STA套件内的任何COM组件操作,实际上是单线程操作,COM组件不必关心线程同步的细节,因为根本没有必要进行线程同步。

如果一个COM组件是MTA的,可以安全的运行与STA套件中。

由于STA套件所有的COM组件代码都运行于主STA(第一个调用CoInitialize函数的线程),如果你的主线程没有调用CoInitialize,那么第一个调用CoInitialize的工作线程就会成为主STA,而工作线程随时可能中止,这种情况下,一旦工作线程中止主STA也就不复存在了,因此你需要在主线程中调用CoInitialize初始化主STA,即使主线程不使用任何COM组件。

MTA

多线程套间,所有COM组件都运行在本线程的MTA套件中。

这是就会出现多个线程同时执行某个COM调用,COM组件的开发者必须预料并处理这种并发访问带来的内存竞争读写混乱。COM组件开发者通常会应用临界区、互斥量、信号灯之类的常规线程同步方法。而调用者,不需要担心COM组件是否会因为多线程挂掉。

如果一个COM组件是STA的,被错误的运行与MTA套件会引发各种奇怪的错误。

把STA的COM组件运行于MTA套件中会引发错误。

这就会引出一个问题,到底我该使用STA还是MTA呢,答案很简单问该COM组件的开发者,或者看他的说明文档,他们会告诉你。

STA套件的初始化方式(两种方式等效):

1,CoInitialize(nil);

2,CoInitializeEx(nil,COINIT_APARTMENTTHREADED);

MTA套间的初始化方式:

1,CoInitializeEx(nil,COINIT_MULTITHREADED);

多线程调用COM组件的体会(CoInitialize)的更多相关文章

  1. 多线程调用COM组件的体会(CoInitialize)(转)

    原文转自 https://www.cnblogs.com/manors/archive/2010/05/17/COM_Initialize_STA_MTA.html 与设备打交道时,我们经常用到COM ...

  2. VS2010调用Com组件

    Com组件开发过程中用的不多,资料也不多,故记录开发Com组件中的部分问题. 在这一篇文章里,讲解了如何使用VS2010创建Com组件.现在基于该文章创建的Com组件接口,创建VC++项目来调用该接口 ...

  3. VC中调用COM组件的方法(转载)

    原文参考:http://hi.baidu.com/mingyueye/item/53ebecd44da76917d80e4449 总结一下在VC中调用COM组件的方法 准备及条件: COM服务器为进程 ...

  4. vc中调用Com组件的方法详解

    vc中调用Com组件的方法详解 转载自:网络,来源未知,如有知晓者请告知我.需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGet ...

  5. 【转】 Pro Android学习笔记(七一):HTTP服务(5):多线程调用HttpClient

    目录(?)[-] 应用共享HttpClient对象的同步问题 创建共享HttpClient代码 创建共享对象 创建可共享的HttpClient对象 使用共享HttpClient对象的代码 基础代码 修 ...

  6. 解决C#调用COM组件异常来自 HRESULT:0x80010105 (RPC_E_SERVERFAULT)的错误

    最近C#调用COM时,遇到了异常来自 HRESULT:0x80010105 (RPC_E_SERVERFAULT)的错误 后面找了一下,发现是在线程里调用COM组件引起的. C++调用COM时,会调用 ...

  7. Titanium中调用ios组件时语言不是本地化的解决方法

    用Titanium开发的ios应用中,当调用系统组件时,尽管手机已经设置了系统语言为中文,但那些组件的界面却仍为英文.比如调用iphone中的相册组件,其界面为: 那么怎么让它跟系统语言保持一致呢? ...

  8. .NET通过调用Office组件导出Word文档

    .NET通过调用Office组件导出Word文档 最近做项目需要实现一个客户端下载word表格的功能,该功能是用户点击"下载表格",服务端将该用户的数据查询出来并生成数据到Word ...

  9. 服务器端调用Word组件读取Word权限、未将对象引用到对象实例终极解决方案

    最近因为业务需要,需要在服务器上调用Word组件,结果遇到各种问题,比如检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败 ...

随机推荐

  1. @click.native 会触发原生 click事件 vue

    @click.native 会触发原生 click事件 vue

  2. docker 框架概述

    docker的框架 docker 使用传统的client-server架构模式,用户端通过docker client 与docker  daemon 建立通信,并将请求发送给后者,而docker后端时 ...

  3. CNN完成mnist数据集手写数字识别

    # coding: utf-8 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data d ...

  4. 云服务器linux使用之开发环境搭建(一)

    Host key verification failed. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: ...

  5. 【转】C#中的==、Equal、ReferenceEqual

    [转]C#中的==.Equal.ReferenceEqual 转载自: http://www.cnblogs.com/zagelover/articles/2741409.html 1. Refere ...

  6. 内置函数filter和map

    filter filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回 ...

  7. minGW64编译Qt

    1.安装minGW64,设置bin目录到环境变量Path 2.cmd 到qt的Src目录 3.configure -debug-and-release -opensource -prefix &quo ...

  8. 【模板】插头dp

    题目描述 题解: 插头$dp$中经典的回路问题. 首先了解一下插头. 一个格子,上下左右四条边对应四个插头.就像这样: 四个插头. 一个完整的哈密顿回路,经过的格子一定用且仅用了两个插头. 所以所有被 ...

  9. git 知识(转)

    转自:http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html Workspace:工作区 Index / Stage:暂存区 Repos ...

  10. python 学习总结3

    Python蟒蛇绘制 一.实现程序如下 import turtle turtle.setup (650, 350, 200, 200)#turtle的绘图窗体turtle.setup(width, h ...