我使用vc6.0的atl向导创建了一个组件(接口是ITdtInterface,实现类是CTdtInterface,连接点_ITdtInterfaceEvents.连接点事件函数为Fire_SendEvt()).在组件中我创建了一个线程.当我的线程接受到数据时,调用一个事件函数.
CTdtInterface* pEvent;
pEvent->Fire_SendEvt();
编译没有任何错误,运行时,当调用Fire_SendEvt()出现异常.进入Fire_SendEvt()函数内检查,是在int nConnections = m_vec.GetSize();这一句发生错误.
麻烦各位指教.

解决方案 »

  1.   

    好像不能这样直接调用吧?
    CTdtInterface* pEvent;
    pEvent->Fire_SendEvt();
    这样是Fire不出来的。必须通过Marshal接口或是PostMessage的形势来做。跨线程发FireEvent
         相关参考:
                 http://support.microsoft.com/kb/q206076/
                 http://www.evget.com/articles/evget_780.html
         问题描述如下:
              对于一个在非主线程发出的事件,Visual Basic 和IE等ActiveX容器接收不到(PRB: Firing Event in Second Thread Causes IPF or GPF ),
         微软的解决办法是利用PostMessage,timer等异步消息或是通过CoMarshalInterThreadInterfaceInStream来解决。我在本应有中是用Marshal机制来解决的:
         具体的解决方案可以参考q206076中给出的例子代码。
      

  2.   

    zhujianping_es(DavidRipple)用postmessage怎么用呀?
    是在组件内部的线程中需要发消息的地方调用postmessage吗?
    是不是还得写一个postmessage的回调函数.
      

  3.   

    CTdtInterface* pEvent;
    pEvent->Fire_SendEvt();
    pEvent有没有创建实例啊?
      

  4.   

    我是使用CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream来做的,这需要你定义一个接口,比如我定义了一个:
    interface IErrorMediator:IDispatch
    {
    [id(1), helpstring("method FireErrorEvent")] HRESULT FireErrorEvent(long nEventID, long wParam);
    [id(2), helpstring("method SetUpdaterInstance")] HRESULT SetUpdaterInstance(long pUpdater);
    };
    然后,将这个接口Marshal给开的线程,线程内部通过调用
    CoInitialize(NULL);
    IErrorMediator *pErrorMediator=NULL;
    HRESULT hRes =CoGetInterfaceAndReleaseStream(pThis->m_pStream,IID_IErrorMediator,(LPVOID*)&pErrorMediator);
    然后调用
    pErrorMediator->FireErrorEvent(DOWNLOADER_GET_REQUEST_FAILED,NULL);来发消息,IErrorMediator的实现类再来Fire Event
    STDMETHODIMP CErrorMediator::FireErrorEvent(long nEventID, long wParam)
    {
    switch(nEventID)
    {
    case DOWNLOADER_FILE_DOWNLOAD_START:
    {
    strFileName=(LPCTSTR)wParam;
    m_pUpdater->Fire_OnFileDownload(strFileName);
                
    //Don't forget this 
    delete[] (BYTE*)wParam;
    }
    break;
    ....
    }
      

  5.   

    谢谢zhujianping_es(DavidRipple)
    听你一说我就明白了.我在网上找了好多关于Marshal接口的文章和代码.一直没看明白.看了你的回复,马上对Marshal接口的功能和用法明白了很多.
    衷心谢谢zhujianping_es(DavidRipple).希望以后能关于编程方面向你多多请教.