2015-03-19 2 views
1

Скажет, у меня есть указатель COM интерфейсаКак указатели интерфейса COM относятся к классу реализации?

IMyInterface *pInterface = 0x12696340; 

Я могу видеть из отладчика, следуя вызов функции, что это должно быть реализовано CMyImplementer, но этот класс находится в 0x12686e50.

Вопрос в том, как COM связывает интерфейс с классом реализации? Должен быть какой-то способ конвертировать из интерфейса в указатель класса - как это сделать?

+1

'Должен быть какой-то способ конвертировать из интерфейса в указатель класса' Почему это должно быть? Насколько вам известно, COM-объект реализован, скажем, в Visual Basic, и нет такого понятия, как «класс» за ним. Как вы думаете, для чего вам нужна эта информация? Какую проблему ты пытаешься решить? –

ответ

1

Вот что происходит в одной реализации, с которой я знаком. Не уверен, насколько универсален этот макет, но он может дать вам представление о том, что возможно.

Компоновка класса в памяти, в 32-битном режиме, выглядит следующим образом:

[ (4 bytes) ptr to vtable for IUnknown ] 
[ (4 bytes) ptr to vtable for IDispatch ] 
[ (4 bytes) ptr to vtable for IMyInterface ]  <--- pInterface points to here 
[ (....) member variables of the class implementing CoYourClass etc. ] 

В другом месте в памяти (один экземпляр этого для всех объектов класса):

[ (12 bytes) vtable for CoYourClass::IUnknown ] 
[ (28 bytes) vtable for CoYourClass::IDispatch ] 
[ (4*n bytes) vtable for CoYourClass::IMyInterface ] <---- (*pInterface) points here 

Записи в таблице vtable указывают на thunks. Когда вы вызываете pInterface->Foo();, извлекается запись vtable, соответствующая Foo, которая является кодовым адресом thunk. Этот thunk получает pInterface в качестве указателя this. Thunk знает, что это IMyInterface thunk в классе CoYourClass и в этом случае вычитает фиксированное смещение 8 байт, чтобы получить указатель на начало объекта. Затем thunk вызывает фактический код, который вы написали, для реализации Foo, передавая скорректированный указатель как this.

Примечание к OP: вы можете выяснить, какой формат использует ваш компилятор, проверив память и переменные в вашем отладчике при вызове объекта (проще всего, если ваш отладчик позволяет вам перейти от кода клиента в код сервера для процесса объект)

+0

vtable сам не является частью экземпляра объекта, только указатель vtable. –

+0

@IgorTandetnik спасибо, обновлено –

+0

На самом деле 'pInterface' указывает на четыре байта, которые сами указывают на' IMyInterface' vtable. То, как вы это делаете, никогда не может быть двух разных указателей IMyInterface, ссылающихся на два разных экземпляра 'CoYourClass' (так как все экземпляры' CoYourClass' имеют одну и ту же таблицу vtable).Все это предполагает реализацию учебника «класс, полученный из интерфейса». Существует много других возможных способов реализации. –

0

COM не требует указателей интерфейса, в общем, указывать на один и тот же физический объект; это все зависит от реализации каждого конкретного объекта COM. Однако указатели IUnknown для любого логического объекта должны быть равны и служить как идентификатором объекта. Поэтому вы можете просто QueryInterface за IUnknown и проверить этот указатель, когда вам нужно проверить личность.

+0

Интересно. Я фактически ищу решение отладчика, а не код, хотя, поэтому я не могу вызвать QueryInterface из отладчика. Я думаю, было бы полезно знать, как среда выполнения отображает указатель интерфейса на объект-реализацию. – Ben

+0

@Ben: Как я уже писал, это зависит от реализации объекта COM. Нет гарантированного общего времени выполнения. Это может быть полностью * ad hoc *. –

+0

@Ben: если у вас есть исходный код для объекта, вы можете прочитать его, чтобы определить, как реализуется объект. Если вы этого не сделаете - как именно вы вступаете в реализацию в отладчике? –

Смежные вопросы