CoInitialize()和AfxOleInit()

都是初始化COM库,不同之处在与:

OLE是建立在COM之上的技术,层次比COM要高。AfxOleInit()调用的是OleInitialize(),而 OleInitialize()除了调用CoInitializeEx()来初始化COM库外,还进行一些其它的操作,这些操作对OLE应用来说是必须的,这些OLE应用包括:  
    (1)Clipboard;  
    (2)Drag   and   drop;  
    (3)Object   linking   and   embedding(现在的OLE,已不再仅仅是Object   linking   and   embedding的概念);  
    (4)In-place   activation;  
    与AfxOleInit()对应的是,AfxOleTerm()。

AfxOleInit()和AfxOleTerm()其实也是需要成对的,但是,在你的程序中,AfxOleTerm()可以不出现,这是因为,MFC已经帮你做好了(有兴趣的话,你可以仔细研究一下CWinThread::m_lpfnOleTermOrFreeLib,而CWinApp是从CWinThread继承的)。

注:但是当你的函数出现了重复调用AfxOleInit()时间便不能依靠mfc自动调用了,需要显式的调用AfxOleTerm清理com库

CoInitialize与AfxOleInit

使用MFC的控制台主程序中如果用AfxOleInit()初始化com就会出现DLL中调用wordApp.CreateDispatch("Word.Application",NULL)失败,而改用用CoInitialize()则会成功

在AfxOleInit()函数中设置断点调试之后可以知道:afxContextIsDLL这个标志的值为ture,因而它并不会去调用OleInitialize,进而不会调用CoInitialize.

MSDN(If AfxOleInit is called from an MFC DLL, the call will fail. The failure occurs because the function assumes that, if it is called from a DLL, the OLE system was previously initialized by the calling application.) 看来在这个函数中把当前项目当做DLL来处理了.^_^,不知是不是MFC本身的bug

 BOOL AFXAPI AfxOleInit()
{
_AFX_THREAD_STATE* pState = AfxGetThreadState();
ASSERT(!pState->m_bNeedTerm); // calling it twice? // Special case DLL context to assume that the calling app initializes OLE.
// For DLLs where this is not the case, those DLLs will need to initialize
// OLE for themselves via OleInitialize. This is done since MFC cannot provide
// automatic uninitialize for DLLs because it is not valid to shutdown OLE
// during a DLL_PROCESS_DETACH.
if (afxContextIsDLL)
{
pState->m_bNeedTerm = -; // -1 is a special flag
return TRUE;
} // first, initialize OLE
SCODE sc = ::OleInitialize(NULL);
if (FAILED(sc))
{
// warn about non-NULL success codes
#ifdef _DEBUG
TRACE(traceOle, , _T("Warning: OleInitialize returned scode = %s.\n"),
AfxGetFullScodeString(sc));
#endif
goto InitFailed;
}
// termination required when OleInitialize does not fail
pState->m_bNeedTerm = TRUE; // hook idle time and exit time for required OLE cleanup
CWinThread* pThread; pThread = AfxGetThread();
ASSERT(pThread);
pThread->m_lpfnOleTermOrFreeLib = AfxOleTermOrFreeLib; // allocate and initialize default message filter
if (pThread->m_pMessageFilter == NULL)
{
pThread->m_pMessageFilter = new COleMessageFilter;
ASSERT(AfxOleGetMessageFilter() != NULL);
AfxOleGetMessageFilter()->Register();
}
return TRUE; InitFailed:
AfxOleTerm();
return FALSE;
}

COM中CoInitializeEx 与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来初始化出每个线程自己的套间。

CoInitialize()、CoInitializeEx()和AfxOleInit()区别联系的更多相关文章

  1. COM中的线程模式

      Choosing the threading model for an object depends on the object's function. An object that does e ...

  2. COM线程模型的行为

    原文:https://msdn.microsoft.com/library/ms809971.aspx Behavior of the COM Threading Models COM线程模型的行为 ...

  3. 一个异常研究InvalidApartmentStateChange

    微软资料:invalidApartmentStateChange MDA 地址:https://docs.microsoft.com/zh-cn/dotnet/framework/debug-trac ...

  4. AfxOleInit()和::CoInitialize(NULL)区别

    From: http://blog.csdn.net/zhoubl668/archive/2009/04/30/4139933.aspx OLE是建立在COM之上的技术,层次比COM要高.AfxOle ...

  5. CoInitialize和CoInitializeEx

    1.CoInitialize和CoInitializeEx的功能 CoInitialize是在当前线程初始化Com组件的函数,并且初始化为STA模式(单线程模式),一般新的程序建议使用CoInitia ...

  6. DLL中不能调用CoInitialize和CoInitializeEx

    在项目中为了用API访问Wmi Object来实现命令wmic的功能,所以得使用COM库,使用COM库之前得初始化一些东西. m_hr = CoInitializeEx(, COINIT_APARTM ...

  7. Delphi中CoInitialize之探究

    CoInitialize(LPVOID),它将以特定参数调用CoInitializeEx,为当前单元初始化COM库,并标记协同模式为单线程模式.参数必须为NULL.这是关于OLE和COM的问题. Co ...

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

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

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

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

随机推荐

  1. Windows 8.1 归档 —— Step 3 软件的选择与安装

    这里我将列举出一些 Windows 8.1 下实用的软件 --运行库-- 用精简版系统或者绿色版软件时,使用软件经常遇见的情况是“由于应用程序配置不正确,应用程序未能启动”,提示缺少dll文件等.大部 ...

  2. Git CMD - config: Get and set repository or global options

    命令参数 --get 获取指定的配置项. --global 对于写选项:全局配置,将参数配置于 ~/.gitconfig 而不是仓库目录下的 .git/config.对于读选项:只从 ~/.gitco ...

  3. 学习IT技术的技巧

    怎样学习一个知识A? (1).为什么需要A?  (*) (2).什么是A?  (*) (3).怎么使用A[最简答的]?  (*) (4).使用A时注意的问题?  (*) (5).A的应用领域. (6) ...

  4. 基于DIV+ul+li实现的表格(多示例)

    一个无序列表biaoge,前四个列表项我们赋予了类biaotou.因为这四个项是表格头部,应该与表格数据有所区别.所以单独赋予了类,可以方便控制.下面我们开始CSS代码的编写:由 www.169it. ...

  5. 设置In_Memery

    alter system set inmemory_size=4G scope=spfile; alter table table_name inmemory; alter table table_n ...

  6. 第三十三篇、富文本 NSMutableAttributedString

    // 设置颜色等 NSMutableDictionary *arrDic = [NSMutableDictionary dictionary]; arrDic[NSForegroundColorAtt ...

  7. OC2_使用系统协议

    // // Dog.h // OC2_使用系统协议 // // Created by zhangxueming on 15/6/24. // Copyright (c) 2015年 zhangxuem ...

  8. java学习笔记_GUI(3)

    如何加入自己定义的Panel import javax.swing.*; import java.awt.event.*; import java.awt.*; 5 class MyPanel ext ...

  9. rabbitmq+haproxy+keepalived实现高可用集群搭建

    项目需要搭建rabbitmq的高可用集群,最近在学习搭建过程,在这里记录下可以跟大家一起互相交流(这里只是记录了学习之后自己的搭建过程,许多原理的东西没有细说). 搭建环境 CentOS7 64位 R ...

  10. 6款好用的Python IDE

    “工欲善其事,必先利其器”,如果说编程是程序员的手艺,那么IDE就是程序员吃饭的家伙了.一个优秀的IDE,最重要的就是在普通文本编辑之外,提供针对特定语言的各种快捷编辑功能,让程序员尽可能快捷.舒适. ...