Ошибка при вызове Invoke(реализация IConnectionPointImpl)
От: Антон М Россия  
Дата: 16.02.09 13:58
Оценка:
Добрый день.
Есть два DCOM сервера(один центральный-CCentrSrv, другой локальный — CLocSrv). Хочу организовать механизм событий от локального к центральному.
Прочитал кучу мануала по событиям (даже организовал события от MFC клиента к DCOM — серверу, но вот при варианте DCOM — DCOM вылетает ошибка при возбуждении события, вызове Invoke в CProxy_ILocSrvEvents : public IConnectionPointImpl
Прошу помочь)))
Приведу весь необходимый код:



//Код центрального сервера
class ATL_NO_VTABLE CCentrSrv :
    public CComObjectRootEx<CComMultiThreadModel>,
    public CComCoClass<CCentrSrv, &CLSID_CentrSrv>,
    public IConnectionPointContainerImpl<CCentrSrv>,
    public CProxy_ICentrSrvEvents<CCentrSrv>,
     public IDispatchImpl<ICentrSrv, &IID_ICentrSrv, &LIBID_srvLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
     public IDispEventImpl<1,CCentrSrv,&DIID__ILocSrvEvents,&LIBID_LocalSrvLib,1,0>
{
...
BEGIN_COM_MAP(CCentrSrv)
        ...
    COM_INTERFACE_ENTRY_IID(DIID__ILocSrvEvents,CCentrSrv)
END_COM_MAP()
...
BEGIN_SINK_MAP(CCentrSrv)
    SINK_ENTRY_EX(1,DIID__ILocSrvEvents,1,EventHandler)
END_SINK_MAP()
...
public:
    HRESULT EventHandler()
    {
        MessageBox(NULL,_T("EEEEEE!"),_T("Да детка!!!"),MB_OK);
        return S_OK;
    }
    STDMETHOD(FireLockalServerEvent)(void)
    {
        USES_CONVERSION;
        HRESULT hr;
        IID ifaceIID;
        MULTI_QI* ifaces = NULL ;
        COSERVERINFO csi;
        csi.dwReserved1 = 0;
        csi.dwReserved2 = 0;
        csi.pAuthInfo = NULL;
        csi.pwszName = T2W(_T("localhost"));

        ifaces = new MULTI_QI[1];
        ifaces[0].hr = 0;
        ifaces[0].pItf = NULL;
        ifaceIID = IID_ILocSrv;
        ifaces[0].pIID = (IID*)&ifaceIID;
        hr = CoCreateInstanceEx(CLSID_LocSrv, NULL, CLSCTX_REMOTE_SERVER, &csi, 1, ifaces); 
        if(FAILED(hr))
            return hr;
        ILocSrv* locsrv = (ILocSrv*)ifaces[0].pItf  ;
        //////////////////////////////////////////////////////////////////////////
        IUnknown* pUnk = NULL;
        hr = QueryInterface(IID_IUnknown,(void**)&pUnk);
        DWORD cookie;
        CComQIPtr<IConnectionPointContainer>cpc(locsrv);
        IConnectionPoint* cp = NULL;
        hr = cpc->FindConnectionPoint(DIID__ILocSrvEvents,&cp); 
        hr = cp->Advise(pUnk,&cookie);
        hr = locsrv->FireEvent();
        hr = cp->Unadvise(cookie);
        return hr;
    }
};





//Класс локальн сервера
class ATL_NO_VTABLE CLocSrv :
    public CComObjectRootEx<CComMultiThreadModel>,
    public CComCoClass<CLocSrv, &CLSID_LocSrv>,
    public IConnectionPointContainerImpl<CLocSrv>,
    public CProxy_ILocSrvEvents<CLocSrv>,
    public IDispatchImpl<ILocSrv, &IID_ILocSrv, &LIBID_LocalSrvLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
...
    STDMETHOD(FireEvent)(void)
    {
        Fire_LocalEvent();
        return S_OK;
    }
};
////////
//реализ-я конекшн поинт.. ну и так понятно))))
template <class T>
class CProxy_ILocSrvEvents : public IConnectionPointImpl<T, &__uuidof( _ILocSrvEvents ), CComDynamicUnkArray>
{
    //Warning this class will  be regenerated by the wizard.
public:
    HRESULT Fire_LocalEvent()
    {
        CComVariant varResult;
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        int nConnections = m_vec.GetSize();

        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                varResult.Clear();
                DISPPARAMS disp = { NULL, NULL, 0, 0 };
                HRESULT hr = pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
//Здесь возвращает мне "Ошибка на сервере" и пишет в Output :
//First-chance exception at 0x00000000 in srv.exe: 0xC0000005: Access violation reading location 0x00000000.
//First-chance exception at 0x7c812aeb in LocalSrv.exe: 0x80010105: Ошибка на сервере.
//Причем используя в качестве клиета MFC приложение все было ОК
                if(FAILED(hr))
                    if(DISP_E_EXCEPTION != hr)
                    {
                        varResult.scode = hr;
                        break;
                    }
            }
        }
        return varResult.scode;
    }
};






...
interface ILocSrv : IDispatch{
    [id(1), helpstring("method SubscribeEvent")] HRESULT SubscribeEvent(void);
};
...
library LocalSrvLib
{
...
    dispinterface _ILocSrvEvents
    {
        properties:
        methods:
            [id(1), helpstring("method LocalEvent")] HRESULT LocalEvent(void);
    };
...
    coclass LocSrv
    {
        [default] interface ILocSrv;
        [default, source] dispinterface _ILocSrvEvents;
    };
...
Re: Ошибка при вызове Invoke(реализация IConnectionPointImpl
От: Антон М Россия  
Дата: 17.02.09 12:45
Оценка:
Можете не отвечать Сам разобрался
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.