CoInitialize() 和AfxOleInit()有什么不同

本文详细解析了CoInitialize与AfxOleInit的区别及应用场景。CoInitialize用于基本的COM库初始化,而AfxOleInit不仅初始化COM库,还额外支持OLE特性,如剪贴板、拖放、对象链接与嵌入等。在MFC控制台程序中,使用AfxOleInit可能因特定条件导致失败,此时CoInitialize是更好的选择。

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

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;  // -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, 0, _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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值