读书人

AfxOleInit跟CoInitialize的区别

发布时间: 2013-10-12 11:54:02 作者: rapoo

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()失败,就是因为你的程序在多线程的状态


读书人网 >编程

热点推荐