现在的位置: 首页 > 综合 > 正文

AfxOleInit()和::CoInitialize(NULL)区别及多线程中使用

2013年12月01日 ⁄ 综合 ⁄ 共 2577字 ⁄ 字号 评论关闭

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

Powered by Zoundry Raven

抱歉!评论已关闭.