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
1 BOOL AFXAPI AfxOleInit() 2 { 3 _AFX_THREAD_STATE* pState = AfxGetThreadState(); 4 ASSERT(!pState->m_bNeedTerm); // calling it twice? 5 6 // Special case DLL context to assume that the calling app initializes OLE. 7 // For DLLs where this is not the case, those DLLs will need to initialize 8 // OLE for themselves via OleInitialize. This is done since MFC cannot provide 9 // automatic uninitialize for DLLs because it is not valid to shutdown OLE 10 // during a DLL_PROCESS_DETACH. 11 if (afxContextIsDLL) 12 { 13 pState->m_bNeedTerm = -1; // -1 is a special flag 14 return TRUE; 15 } 16 17 // first, initialize OLE 18 SCODE sc = ::OleInitialize(NULL); 19 if (FAILED(sc)) 20 { 21 // warn about non-NULL success codes 22 #ifdef _DEBUG 23 TRACE(traceOle, 0, _T("Warning: OleInitialize returned scode = %s.\n"), 24 AfxGetFullScodeString(sc)); 25 #endif 26 goto InitFailed; 27 } 28 // termination required when OleInitialize does not fail 29 pState->m_bNeedTerm = TRUE; 30 31 // hook idle time and exit time for required OLE cleanup 32 CWinThread* pThread; pThread = AfxGetThread(); 33 ASSERT(pThread); 34 pThread->m_lpfnOleTermOrFreeLib = AfxOleTermOrFreeLib; 35 36 // allocate and initialize default message filter 37 if (pThread->m_pMessageFilter == NULL) 38 { 39 pThread->m_pMessageFilter = new COleMessageFilter; 40 ASSERT(AfxOleGetMessageFilter() != NULL); 41 AfxOleGetMessageFilter()->Register(); 42 } 43 return TRUE; 44 45 InitFailed: 46 AfxOleTerm(); 47 return FALSE; 48 }
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来初始化出每个线程自己的套间。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述