[default.source] дуальные интерфейсы и позднее связывание
От: SloNN  
Дата: 24.04.03 08:22
Оценка:
Вопрос в следующем:
мне нужно написать объект, который бы перехватывал обычные event'ы через IConnectionPoint и запускал бы их на переданном мне IDispatch. Я загружаю tlb, вычитываю оттуда нужный мне интерфейс, выполняю advise на объекте-источнике событий. Но возникает проблема: если посмотреть в код метода advise в ATL реализации, то там есть такой кусок:


    hRes = pUnkSink->QueryInterface(iid, (void**)&p);
    if (SUCCEEDED(hRes))
    {
        pT->Lock();
        *pdwCookie = m_vec.Add(p);
        hRes = (*pdwCookie != NULL) ? S_OK : CONNECT_E_ADVISELIMIT;
        pT->Unlock();
        if (hRes != S_OK)
            p->Release();
    }
    else if (hRes == E_NOINTERFACE)
        hRes = CONNECT_E_CANNOTCONNECT;
    if (FAILED(hRes))
        *pdwCookie = 0;


где iid — CLSID интерфейса-источника событий (для определенности дальше я буду его называть IID_Event), для которого я говорю advise.
Т.е получается, что ATL делает дополнительную проверку и проверяет, действительно ли переданный ему указатель на интерфейс поддерживает интерфейс-источник событий (IID_Event).

И вроде бы все хорошо, но я ( и другие языки, поддерживающие позднее связывание) не могу в QueryInterface ответить, что я поддерживаю на двоичном уровне IID_Event. Я могу честно ответить, что я поддерживаю IUnknown и IDispatch.
Дальше если посмотреть исходники запуска событий в ATL будет все равно видно, что события вызываются через IDispatch.
Т.е. я могу формально подправить QueryInterface и добавить туда строчку, что я поддерживаю IID_Event, но если вдруг объект-источник событий решит вызвать через указатель методы IID_Event напрямую, не через IDispatch, то тут же получит ошибку доступа к памяти.

Я поискал по интернету, но наткнулся лишь на одну статью с borland'a, где они решают похожую задачу, так там они действительно в QueryInterface объявляют о поддержке IID_Event, но возвращают просто указатель на IDispatch.

Может быть есть какие-нибудь соглашения о вызове методов на [default,source] интерфейсах?
Или нужна какая-нибудь дополнительная обработка?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.