CoInitialize()、CoInitializeEx()和AfxOleInit()区别联系
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()区别联系的更多相关文章
- COM中的线程模式
Choosing the threading model for an object depends on the object's function. An object that does e ...
- COM线程模型的行为
原文:https://msdn.microsoft.com/library/ms809971.aspx Behavior of the COM Threading Models COM线程模型的行为 ...
- 一个异常研究InvalidApartmentStateChange
微软资料:invalidApartmentStateChange MDA 地址:https://docs.microsoft.com/zh-cn/dotnet/framework/debug-trac ...
- AfxOleInit()和::CoInitialize(NULL)区别
From: http://blog.csdn.net/zhoubl668/archive/2009/04/30/4139933.aspx OLE是建立在COM之上的技术,层次比COM要高.AfxOle ...
- CoInitialize和CoInitializeEx
1.CoInitialize和CoInitializeEx的功能 CoInitialize是在当前线程初始化Com组件的函数,并且初始化为STA模式(单线程模式),一般新的程序建议使用CoInitia ...
- DLL中不能调用CoInitialize和CoInitializeEx
在项目中为了用API访问Wmi Object来实现命令wmic的功能,所以得使用COM库,使用COM库之前得初始化一些东西. m_hr = CoInitializeEx(, COINIT_APARTM ...
- Delphi中CoInitialize之探究
CoInitialize(LPVOID),它将以特定参数调用CoInitializeEx,为当前单元初始化COM库,并标记协同模式为单线程模式.参数必须为NULL.这是关于OLE和COM的问题. Co ...
- 多线程调用COM组件的体会(CoInitialize)(转)
原文转自 https://www.cnblogs.com/manors/archive/2010/05/17/COM_Initialize_STA_MTA.html 与设备打交道时,我们经常用到COM ...
- 多线程调用COM组件的体会(CoInitialize)
调用任何COM组件之前,你必须首先初始化COM套件环境,即调用CoInitialize或CoInitializeEx.COM套件环境在线程的生存周期内有效,线程退出前需要调用CoUninitializ ...
随机推荐
- poj 3155 最大密度子图
思路: 这个还是看的胡伯涛的论文<最小割在信息学竞赛中的应用>.是将最大密度子图问题转化为了01分数规划和最小割问题. 直接上代码: #include <iostream> # ...
- Linux时间函数
一.时间编程 1.核心理论 (1).时间类型 2.函数学习 (1).获取日历时间 函数名:time 函数原型:time_t time(time_t *t) 函数功能:获取当前日历时间 所属头文件:&l ...
- poj 2524 Ubiquitous Religions(宗教信仰)
Ubiquitous Religions Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 30666 Accepted: ...
- (转)TCP三次握手
原文地址:http://www.cnblogs.com/rootq/articles/1377355.html TCP(Transmission Control Protocol) 传输控制协议 TC ...
- 自定义ListView适配器
继承BaseAdapter类 覆盖以下4个方法: @Override public int getCount() { return users.size(); } @Override public O ...
- 【Unix环境高级编程】编写变长参数函数
文件的格式输入输出函数都支持变长参数.定义时,变长参数列表通过省略号'...'表示, 因此函数定义格式为: type 函数名(parm1, parm2,parmN,...); Unix的变长参数通过v ...
- Swift属性
属性的存储 属性的主要作用是存储数据,可以常量属性和变量属 性: struct FixedLengthRange { var firstValue: Int let length: Int } var ...
- IOS中的内存不足警告处理(译)
由于在IOS中虚拟内存系统不会采用页置换的方式来获取请求内存,取而代之的是它通过移除应用程序中的强引用来释放一些内存资源,我们知道强引用在IOS中表示拥有关系,只要有至少一个变量拥有这个对象,那么对象 ...
- 如何测量一个嵌入式Linux系统的功耗/power dissipation/power wastage/consumption
参考: 1.Linux Circuit Software To Calculate Power Dissipation
- 使用git的正确姿势
1.Windows上安装git:从https://git-for-windows.github.io下载msysgit. 2.linux(Debian或Ubuntu)安装git:sudo apt-ge ...