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

来源:互联网 发布:个人自动发卡源码带wap 编辑:程序博客网 时间:2024/05/21 15:50

在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;
}

原创粉丝点击