OleInitialize、CoInitialize、CoInitializeEx和AfxOleInit()区别

本文深入探讨了COM初始化函数CoInitialize和OleInitialize的区别及用法,包括它们如何初始化COM库,支持多线程的机制,以及在不同场景下的应用实例。重点介绍了CoInitializeEx的灵活性和推荐使用的场合,同时提到了AfxOleInit作为MFC框架下简化COM初始化的封装。最后,通过实例展示了在使用ADO访问ACCESS时遇到卡顿问题时,确保正确初始化COM的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()。
在 C++ 中,`OleInitialize` 函数用于初始化OLE (Object Linking and Embedding) 库。这是一个非常重要的步骤,在应用程序中如果打算使用 COM (Component Object Model) 或 OLE 技术来创建、嵌入或其他方式操作复合文档时就必须调用此函数。 ### 功能说明 当你调用了 `OleInitialize()` 之后,系统会完成以下几个任务: - 初始化线程的状态以便它可以参与 COM 操作; - 设置当前线程为 STA(单线程单元,默认情况),除非特别指定 MTA (多线程单元)模式; - 确保在同一进程中只有一个实例能够成功地初始化 OLE/COM 系统库。 需要注意的是每个成功的 `OleInitialize` 调用都应该有一个对应的 `OleUninitialize` 调用来释放资源并清理环境变量等设置。 ### 参数列表 该函数接受一个指向空的 DWORD 类型指针作为其唯一的参数,通常传入 NULL 即可。如果你想要获取更详细的初始化信息也可以传递有效的地址过去: ```c++ HRESULT hr = OleInitialize(NULL); // 最简单的用法就是传入NULL if FAILED(hr){ // 错误处理... } ``` 另外请注意从 Windows Vista 开始推荐使用的 API 已经改为 CoInitializeEx,因为它允许更细粒度控制如何配置特定线程模型(MTA or STA). ### 返回值 返回 HRESULT 数据类型的结果码指示操作是否成功以及发生错误的原因。一般情况下只要检查结果是不是 S_OK 就能确定初始化动作有没有顺利完成。 例如我们可以像下面这样写一段包含异常处理机制的小程序片段来进行正确的初始化与反初始化流程管理: ```cpp #include <windows.h> #include <comdef.h> int main(){ HRESULT hr; // 尝试初始化 OLE / COM 环境. hr = OleInitialize(NULL); if(FAILED(hr)){ _com_error error(hr); printf("Failed to initialize: %s\n",error.ErrorMessage()); return -1; } // ... 执行其他依赖于已初始化状态的操作 ... // 正确关闭 OLE / COM 支持前做的收尾工作. OleUninitialize(); return 0; } ``` 最后提醒一点:因为现代操作系统版本逐渐淘汰了对旧式API的支持所以建议尽量利用更新更好的替代品比如上面提到过的CoInitializeEx函数.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值