COM组件初始化

转载 2015年07月07日 13:59:03

用DirectShow到了枚举设备,放在程序开始出,没有任何输出结果,查代码发现用的:

    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum,  (void **) &p->pICreateDevEnum);
 返回值居然错误,才恍然大悟,原来是没有初始化COM组件。

加上:

CoInitializeEx(NULL,COINIT_MULTITHREADED|COINIT_SPEED_OVER_MEMORY);

一切正常:)

 

顺便查了下:

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

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





OleInitialize、CoInitialize、CoInitializeEx和AfxOleInit()区别

  
CoInitialize CoInitializeEx 是用来初始化COM运行环境的。
OleInitialize是初始化Ole的运行环境,Ole是在Com的基础上作的扩展,是ActiveX运行的基础,OleInitialize肯定会调用CoInitialize。

CoInitialize、CoInitializeEx都是windows的API,主要是告诉windows以什么方式为程序创建COM对象,原因是程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
    CoInitialize指明以单线程方式创建。
    CoInitializeEx可以指定COINIT_MULTITHREADED以多线程方式创建。
    创建单线程方式的COM服务器时不用考虑串行化问题,多线程COM服务器就要考虑。
    CoInitialize并不装载com库,这个函数只是用来初始化当前线程使用什么样的套间。当使用这个函数以后,线程就和一个套间建立了对应关系。
    线程的套间模式决定了该线程如何调用com对象,是否需要列集等
    套间是com中用来解决并发调用冲突的很有效的办法
    Before calling any COM functions, a thread needs to call CoInitialize to load the COM infrastructure (and to enter an apartment). Once a thread calls CoInitialize, the thread is free to call COM APIs.
    CoInitializeEx provides the same functionality as CoInitialize and also provides a parameter to explicitly specify the thread's concurrency model. The current implementation of CoInitialize calls CoInitializeEx and specifies the concurrency model as single-thread apartment. Applications developed today should call CoInitializeEx rather than CoInitialize.
    注:新的应用程序应该调用CoInitializeEx而不是CoInitialize,否则就会有必要在之后每个调用Com的线程中调用CoInitialize来初始化出每个线程自己的套间。

 AfxOleInit实际上调用了OleInitialize,虽然它在内部也调用了CoInitializeEx,但它只能处理单线程,这是AfxOleInit和CoInitialize主要区别:   
  OleInitialize   calls   CoInitializeEx   internally   to   initialize   the   COM   library   on   the   current   apartment.   Because   OLE   operations   are   not   thread-safe,  OleInitialize   specifies   the   concurrency   model   as   single-thread   apartment.     
  Once   the   concurrency   model   for   an   apartment   is   set,   it   cannot   be  changed.   A   call   to   OleInitialize   on   an   apartment   that   was   previously  initialized   as   multithreaded   will   fail   and   return   RPC_E_CHANGED_MODE.

应用:
1. CoInitialize 仅仅初始化Com,支持多线程。也就是说如果多线程调用Com接口,必须在每个线程中都调用CoInitialize。
2. OleInitialize 初始化Com(其实也是调用CoInitializeEx),支持多线程。比CoInitialize多了一下内容:
A) Clipboard
B) Drag and drop
C) Object linking and embedding (OLE)
D) In-place activation
如果不需要这些,用CoInitialize就可以。
3. AfxOleInit是MFC对OleInitialize的封装。貌似不支持多线程,也就是说只能在主进程调用该函数,如果线程需要使用Com必须调用上面的两个来实现初始化。而且MSDN明确标明AfxOleInit不能在MFC的DLL中调用,否则也会造成初始化失败。
4.OleInitialize和OleUninitialize( )成对使用;CoInitialize和CoUninitialize成对使用;CoInitializeEx和CoUninitialize成对使用;AfxOleInit()由MFC自动释放。

VC++使用ADO访问ACCESS时,出现_RecordsetPtr Open卡或者_ConnectionPtr Excute卡或者_CommandPtr Excute一直卡住等莫名其妙的情况时,而语法又没有错误时,请确定初始化COM函数。
MFC程序建议使用AfxOleInit()。

COM组件初始化

OleInitialize、CoInitialize、CoInitializeEx和AfxOleInit()区别  (2012-06-28 22:49:25) 转载▼ 标...
  • chinabinlang
  • chinabinlang
  • 2014年04月15日 11:43
  • 7280

多线程中对COM的初始化CoInitialize应该注意的问题

使用COM组件时,通常的做法是在main函数的最前面调用CoInitialize(NULL);,最后面调用CoUninitialize(); 今天遇到一个问题是在线程中使用COM组件失败了,我就怀疑...
  • mfcing
  • mfcing
  • 2015年04月18日 22:02
  • 4948

COM组件的智能指针(深入浅出)

作者:王卫星   csdnid:wangweixing2000 职能指针其实只是为了我们开发者方便使用的东东,但是大多数据开发者总是害怕会有泄漏,以前的字符串的泄漏问题大家都应该知道了。atl7的出现...
  • wangweixing2000
  • wangweixing2000
  • 2005年08月03日 12:20
  • 3931

com组件初始化的几个方法

本篇幅参考http://www.vckbase.com/document/viewdoc/?id=1500代码总结了几种的com初始化的方法  1. 经过 IUnknown得到 IFun 接口指针 C...
  • rabbitguiming
  • rabbitguiming
  • 2009年11月15日 23:42
  • 5876

COM组件的初始化

任何一个使用COM组件的windows程序在初始化COM库的时候都要调用CoInitializeEx函数,每一个使用COM接口的线程必须单独调用这个函数。...
  • youjiaqu
  • youjiaqu
  • 2016年02月15日 10:36
  • 613

多线程中使用COM组件时的初始化问题

CoInitialize、CoInitializeEx都是windows的API,主要是告诉windows以什么方式为程序创建COM对象,原因是程序调用com库函数(除CoGetMalloc和内存分配...
  • chenlycly
  • chenlycly
  • 2014年10月07日 15:19
  • 4174

COM组件的接口和对象

一、 前言 在COM规范中,最基本的两个要素就是对象与接口,因为COM就是由这两者来共同实现的。COM对象在组件中是被封装起来的,客户代码只能通过接口来访问COM对象并享受其服务,由于客户与COM...
  • u010523811
  • u010523811
  • 2017年02月07日 17:21
  • 2086

Windows下Qt5.2 使用COM组件操作 Execl

这两天使用QT编写程序,需要用到操作和读取Execl文件。学习了它的平台相关特性。Qt   提供了与平台相关的编程接口,对于windows系统Qt提供了ActiveQt框架。 ActiveQt有...
  • kello219
  • kello219
  • 2014年05月29日 00:46
  • 1783

com组件初始化

今天做一个检测tuner的小程序,用到了枚举设备,没有任何输出结果,查代码发现用的:    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, ...
  • sanfenlu
  • sanfenlu
  • 2010年06月22日 18:13
  • 3110

初始化COM组件

 #import "C:/Program Files/Common Files//ActiveX//test.dll" rename_namespace("testLib")/ rename("Fre...
  • afterry
  • afterry
  • 2009年04月02日 16:06
  • 322
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:COM组件初始化
举报原因:
原因补充:

(最多只允许输入30个字)