C ++ DispInvoke не может найти член

Сценарий такой:

  • У меня есть COM-объект, чтобы задавать вопросы. Назовите его ICom.
  • Объект COM требует от меня реализации IDispatch, потомка, скажем, IComEvents, который уведомляет меня о событиях.
  • Я реализую IDispatch и подключаю его к COM-интерфейсу.

Все идет нормально. Invoke () моего потомка IComEvents вызывается, когда происходят события.

Дело в том, что я должен вручную проанализировать параметры Invoke (). Например, если функция уведомления HRESULT OnMouseHit (int x), мне нужно обнаружить эту функцию по DispID, а затем вызвать ее вручную, например

if (dispIdMember == 0xfa)
 {
 OnMouseHit(pDispParams->rgvarg[0].pIntVal); 
 }

Мне пришлось бы сделать это для всех функций, которые я хочу реализовать. Однако я видел функцию DispInvoke (), которая предположительно автоматически сделает это за меня и вызовет соответствующий перегруженный метод для dispId с правильными параметрами:

DispInvoke(this,m_ptinfo,dispIdMember,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);

Как мне сгенерировать m_ptinfo? Вызов LoadRegTypeLib с libid COM-объекта, а затем ITypeLib :: GetTypeInfoOfGuid () с IID IComEvents. Однако DispInvoke () всегда возвращает «член не найден».

Что было бы не так? Я ожидаю, что DispInvoke проанализирует информацию о типе, найдет имя функции-члена из DispID, а затем с помощью указателя «this» получит адрес функции из vtbl.

Что я делаю неправильно?

Большое спасибо. Майкл.


person Michael Chourdakis    schedule 25.08.2011    source источник


Ответы (1)


IComEvents - двойной интерфейс или диспетчерский интерфейс? Если это чистый диспетчерский интерфейс, у него нет vtable. DispInvoke требует, чтобы у интерфейса была vtable (т. Е. Чтобы это был двойной интерфейс).

person ymett    schedule 25.08.2011
comment
Я понимаю. Это должен быть интерфейс без vtable. Но в чем тогда смысл DispInvoke? Почти все интерфейсы уведомлений в Windows построены одинаково. - person Michael Chourdakis; 25.08.2011
comment
@Michael Я предполагаю, что DispInvoke предназначен для реализации обычных двойных интерфейсов (где разработчик, как правило, также является создателем интерфейса), а не интерфейсов событий (обратный вызов, уведомление), где разработчик конкретно не является создателем интерфейса. Обратите внимание, что обычно нет потерь в создании двойного интерфейса, а не диспетчерского интерфейса, но для интерфейса событий, делающего его двойным, означало бы, что языки сценариев (которые не могут создавать vtables) не смогут получать события. - person ymett; 31.08.2011