一个COM异步实现接口列集(Marshal)源代码实例

在COM中实现异步是非常复杂但又非常有用的。Process如下:

1. 列集要在线程里使用的接口。

2.Create一个线程。

3. 在线程里Release列集。

4. 调用接口的方法。

头文件如下:

class ATL_NO_VTABLE CAsync
{
protected:
CAsync();
virtual ~CAsync();
private:
unsigned int RunThread();
static unsigned int __stdcall ThreadFunction(void *pFun); //线程函数
HANDLE m_hThread;
protected:
STDMETHOD(EnableAsyncFunction)( IUnknown *pUnkSink); //异步的方法,传入需要列集的接口
/////////////////////////////////////////////////////////////////////
IStream *m_pIStream;
};

源文件如下:

STDMETHODIMP CAsync::EnableAsyncFunction( IUnknown *pUnkSink)
{
HRESULT hr = S_OK;
_AsyncNeedMarshal *m_pIHelper=0;
hr = pUnkSink->QueryInterface(IID__NEED, (void**)&m_pIHelper);

if (SUCCEEDED(hr))
{

//列集m_pIHelper
if( FAILED( ::CoMarshalInterThreadInterfaceInStream(IID__AsyncNeedMarshal,m_pIHelper, &m_pIStream)) )
{
return S_FALSE;
}

m_pIHelper->Release();
}
if (SUCCEEDED(hr))
{
DWORD threadID = 0;

//起线程
m_hThread =CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, this, 0, &threadID);
if (0 == m_hThread)
{
hr = E_FAIL;
m_hThread = INVALID_HANDLE_VALUE;
}
}

return hr;
}

unsigned int __stdcall CAsync::ThreadFunction(void *pFun)
{
unsigned int result = 0;

if (pFun)
{
::CoInitialize(0);

//线程函数调用RunThread()方法,真正的运行内容在RunThread()内。
CAsyncMessageReceive &me = *(CAsyncMessageReceive*)pFun;
result = me.RunThread();
::CoUninitialize();
}
return result;
}


unsigned int CAsync::RunThread()
{
_AsyncNeedMarshal *m_pIHelper=0;

//反列集,注意抛出异常的原因有:列集的接口没有在注册表里注册。
HRESULT hr = ::CoGetInterfaceAndReleaseStream(m_pIStream, IID__AsyncNeedMarshal, (void**)&m_pIHelper );

//得到接口对象指针,可以调用该对象的方法了。
m_pIHelper ->Function();

if (m_pIHelper!=NULL)
{
m_pIHelper->Release();
m_pIHelper= 0;
}
return 0;
}

你可能感兴趣的:(marshal)