首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

AfxOleInit跟CoInitialize的区别

2013-10-12 
AfxOleInit和CoInitialize的区别在vc6中编译一个MFC程序时其中有段代码在创建数据库连接报错。其源码如下:

AfxOleInit和CoInitialize的区别

在vc6中编译一个MFC程序时其中有段代码在创建数据库连接报错。

  其源码如下:

   其中声明

   _ConectPtr m_pConn,在函数中

    HRESULT hr = m_pConn.CreateInstance(__uuidof(Connection));  //_T("ADODB.Connection"));
    if(FAILED(hr))
    {       
          return false;
    }

   后来在检查,发现需要调用AfxOleInit()初始化组件即可解决。而我在文件中是加入了::CoInitialize(),但是在实际运行中该函数并没有起到作用。

而在所宣言中,AfxOleInit包含了CoInitialize()。但是为啥AfxOleInit能解决数据连接的CreateInterface问题呢?观察

AfxOleInit的源码。
--------------------------------------------  
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);    //该句子做初始化ole
    if (FAILED(sc))
    {
        // warn about non-NULL success codes
        TRACE1("Warning: OleInitialize returned scode = %s.\n",
            AfxGetFullScodeString(sc));
        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();
    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;
}

可见,AfxOleInit()是封装了OleInitialize()来初始化com组件;
查询网上资料说:OleInitialize内部调用了CoInitialize 。在OleInitialize比ConInitialize多了以下支持:  
  Clipboard    
  Drag   and   drop    
  Object   linking   and   embedding   (OLE)    
  In-place   activation    
  如果你不需要这些附加功能,就用CoInitialize或CoInitializeEx。

但是在本人程序中调用CoInitialize不行而AfxOleInit可以,难道OleInitialize中创建的所附几个在ADO com控件上用到,但是在写了一个控制台上的ado程序,调用CoInitialize却是可行的。其中细节和玄妙打个标记,容以后在研究吧,偷懒了,如果发现CoInitalize不行就用AfxOleInit吧。

0-----

汗颜:因为在app的InitInstance中的粗心末尾加了一句::UnCoInitialize(),造成coinitalize错误。实际上2个函数都可以初始化ado组件。mark。




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()。   
    
    

    CoInitialize和CoUninitialize必须成对使用,后者不必。

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

////////////////////////////////////////

//以下是AfxOleInit的源码  
  --------------------------------------------  
  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  
  TRACE1("Warning:   OleInitialize   returned   scode   =   %s./n",  
  AfxGetFullScodeString(sc));  
  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();  
  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;  
  }  
   
  可见,AfxOleInit()主要是封装了OleInitialize(),而OleInitialize内部调用了ConInitialize  
  OleInitialize比ConInitialize多了以下支持:  
  Clipboard    
  Drag   and   drop    
  Object   linking   and   embedding   (OLE)    
  In-place   activation    
   
  如果你不需要这些附加功能,就用CoInitialize或CoInitializeEx.

///////////////////////////////////////////////////////////////////////////////////////////

多线程问题的

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.    
   
  所以,你最初调用AfxOleInit()失败,就是因为你的程序在多线程的状态


热点排行