Здравствуйте, silart, Вы писали:
S>S>ConnectionPoint::ConnectionPoint(IConnectionPointContainer* pIConnectionPointContainer, IID iid)
S>: m_dwNextCookie(0), event_id(iid)
S>{
S> ML_ASSERT(pIConnectionPointContainer != NULL);
S> pContainer = pIConnectionPointContainer; // AddRef is not needed.
S> HRESULT hr = CoCreateInstance(CLSID_StdGlobalInterfaceTable,
S> NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)&pGIT);
S> ML_ASSERT( SUCCEEDED(hr) );
S>}
S>ConnectionPoint::~ConnectionPoint()
S>{
pGIT->>Release();
S>}
S>STDMETHODIMP ConnectionPoint::GetConnectionInterface(IID* piid)
S>{
S> if (piid == NULL)
S> {
S> return E_POINTER;
S> }
S> *piid = event_id;
S> return S_OK;
S>}
S>STDMETHODIMP ConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer** ppIConnectionPointContainer)
S>{
S> if (ppIConnectionPointContainer == NULL)
S> {
S> return E_POINTER;
S> }
S> *ppIConnectionPointContainer = pContainer;
S> pContainer->AddRef();
S> return S_OK;
S>}
S>STDMETHODIMP ConnectionPoint::Advise(IUnknown* pIUnknownSink, DWORD* pdwCookie)
S>{
S>com_ptr<IUnknown, IID_IUnknown> pI;
S>HRESULT hr;
S> if (pIUnknownSink == NULL || pdwCookie == NULL)
S> {
S> *pdwCookie = 0;
S> return E_POINTER;
S> }
S> hr = pIUnknownSink->QueryInterface(event_id, (void**)&pI);
S> if (SUCCEEDED(hr))
S> {
S> hr = pGIT->RegisterInterfaceInGlobal(pI, IID_IDispatch, &m_dwNextCookie);
S> ML_ASSERT( SUCCEEDED(hr) );
S> return S_OK;
S> }
S> else
S> {
S> return CONNECT_E_CANNOTCONNECT;
S> }
S>}
S>STDMETHODIMP ConnectionPoint::Unadvise(DWORD dwCookie)
S>{
S> pGIT->RevokeInterfaceFromGlobal(m_dwNextCookie);
S> return S_OK;
S>}
S>
Прочитав этот Ваш пример, я сделал то же самое. Переопределил методы Advise и Unadvise, добавив в них занесение интерфейса в GIT.
Действительно, интерфейс регистрируется в GIT, hr = S_OK, а потом удачно дерегистрируется.
И интерфейс достается из GIT без проблем. Но при отработке ничего не происходит. Почему это может быть, Вы, скорее всего, уже обошли этот вопрос.
Вот код:
template <class T>
STDMETHODIMP TEvents_UpTask<T>::Advise(IUnknown* pUnkSink,
DWORD* pdwCookie)
{
T* pT = static_cast<T*>(this);
IUnknown* p;
IID iid;
GetConnectionInterface(&iid);
HRESULT hRes = pUnkSink->QueryInterface(iid, (void**)&p);
if (SUCCEEDED(hRes))
{
pT->Lock();
DWORD myCookie;
gp_GIT->RegisterInterfaceInGlobal(p, IID_IDispatch, &myCookie);
//это std::map<DWORD, DWORD> для хранения всех Cookie
m_GitPointers[*pdwCookie] = myCookie;
pT->Unlock();
}
return hRes;
}
template <class T>
STDMETHODIMP TEvents_UpTask<T>::Unadvise(DWORD dwCookie)
{
...
//Arkady Add
gp_GIT->RevokeInterfaceFromGlobal(m_GitPointers[dwCookie]);
...
}
//метод, который должен вызываться при старте потока, генерирующего данные (такого же, как у Вас).
template <class T> HRESULT
TEvents_UpTask<T>::Fire_OnListenStart(void)
{
DWORD dw;
T * pT = (T*)this;
pT->Lock();
IUnknown ** pp = m_vec.begin();
while (pp < m_vec.end())
{
if (*pp != NULL)
{
dw = (DWORD)pp;
IDispatch* dp;
HRESULT hr = gp_GIT->GetInterfaceFromGlobal(m_GitPointers[dw], IID_IDispatch, (void**)&dp);
if (SUCCEEDED(hr))
{
IUpTaskEvents* Event;
hr = dp->QueryInterface(DIID_IUpTaskEvents, (void**)&Event);
if (SUCCEEDED(hr))
{
Event->OnListenStart();
}
}
}
pp++;
}
pT->Unlock();
}
Так вот, сервер попадает в Event->OnListenStart(); и выполняет этот метод, но при этом клиентский обработчик об этом почему-то не знает.
Когда то же самое событие вызывается в основном потоке сервера, клиентская реализация интерфейса отрабатывает. А тут — нет.
Не знаете, почему?