调用任何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. Solidity 智能合约开发

    需要专用浏览器或部署节点支持. Solidity (中文:固态,固体)是一种语法与Javascript相似的高级语言,它为Ethereum虚拟机(EVM)编译代码而设计. Solidity是静态类型的 ...

  2. iview table 已选项的数据 this.$refs.tables.$refs.tablesMain.getSelection()

    iview table 已选项的数据 this.$refs.tables.$refs.tablesMain.getSelection() 由于我这里table组件是套了两层组件 所以是进入了两个层次拿 ...

  3. CWnd::Updata的作用

    CWnd::Updata的作用 CWnd::UpdateData 调用此成员函数以在对话框中初始化数据,或者取回和验证对话框数据. BOOL UpdateData(BOOL bSaveAndValid ...

  4. aaaaa

    svn://192.168.199.182/anti-counterfeiting/trunk svn://192.168.199.182/anti-ds/trunk/antifake-service ...

  5. Perl monks 的 快速回复

    on Jun 20, 2019 at 11:39 UTC ( #11101620=perlquestion: print w/replies, xml ) Need Help?? jimyokl ha ...

  6. Eclipse的PyDev插件安装及解决安装后找不到的问题

    一.环境 windows 7 64bit eclipse 4.5.2 pydev jdk7u55 二.安装步骤 1. 安装JDK eclipse依赖于Java环境,所以需要安装Java运行环境JRE. ...

  7. ftp上传文件、删除文件、下载文件的操作

    FavFTPUtil.Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ...

  8. POJ-1002-487-3279(字符串)

    487-3279 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 309685 Accepted: 55292 Descripti ...

  9. PHP将数据库的数据转换成json格式

    header('content-type:application/json;charset=utf8');  $results = array();     while ($row = mysql_f ...

  10. Centos7中 mysql5.7 用户 创建 、授权、远程登录

    1.添加用户跟以往版本不同,MySQL5.7 mysql.user表没有password字段,这个字段改成了 authentication_string:这里我们使用命令进行创建用户:  CREATE ...