В моем коде есть вызов функции InvokeHelper. В интернете я обнаружил, что InvokeHelper используется для вызова функции с использованием dwDispID.
Это звонок.
InvokeHelper(0xd, DISPATCH_METHOD, VT_DISPATCH, (void*)&pDispatch, parms, Name);
Теперь я хочу отладить внутри. Но я не знаю, какая функция будет вызвана. 0xd указывает на какую функцию? В проекте также есть файл odl. Будет ли это вызывать какой-то вызов из этого odl? Какая функция?
РЕДАКТИРОВАТЬ:
Я нашел эти строки в верхней части файла cpp.
// Machine generated IDispatch wrapper class(es) created by Microsoft Visual C++
// NOTE: Do not modify the contents of this file. If this class is regenerated by
// Microsoft Visual C++, your modifications will be overwritten.
Похоже, этот класс является оберткой. Но обертка какого класса?
Сначала вам нужно найти определение интерфейса, который вы вызываете и который реализует IDispatch
, Если это ваш собственный интерфейс, он будет внутри .idl или .odl файла в вашем проекте.
Внутри определения интерфейса каждый метод будет иметь [DISPID]
атрибут с соответствующим номером. Вам нужно найти тот, с идентификатором 0xD
или 13. Это твой метод.
«Это вызовет какой-то вызов от этого odl?»
Да, если объект, для которого вы выполняете вызов, является экземпляром класса, определенного в вашем ODL. Трудно сказать, не видя вашего проекта, поскольку из вашего примера неясно, является ли это «внешним» объектом (т.е. определенным и реализованным в другом месте) или объектом из вашего проекта.
Однако в этом случае я бы сказал, что это класс, внешний по отношению к вашему проекту, как вы упомянули сгенерированный класс-оболочку. Это создается, когда вы добавляете в свой проект внешнюю библиотеку COM — оболочка удобно превращает вызовы COM в класс C ++.
Ваш InvokeHelper
уже в каком-то методе — имя этого метода совпадает с именем метода в интерфейсе, производном от IDispatch, который в конечном итоге будет вызван. Следовательно, возможность отладки зависит от того, есть ли у вас код для компонента.
Обычно имя сгенерированной оболочки может указывать на имя компонента COM, который упакован, но это не всегда так (оно всегда похоже на имя класса COM, но в одном COM может быть несколько классов. сервер). Чтобы выяснить, какой именно это COM-класс, вы можете проверить часть вашего заголовочного файла оболочки с помощью следующей строки:
static CLSID const clsid
= { 0x9e3c8066, 0x7f88, 0x11d1, { 0xbb, 0x57, 0x44, 0x45, 0x53, 0x54, 0x0, 0x1 } };
Это CLSID базового COM-класса, и вы можете посмотреть его в реестре, чтобы точно узнать, что такое ProgId класса и в каком dll / exe он размещен. Для более подробной информации смотрите Вот.
Первые 4 главы «Essential COM» предоставьте отличную информацию о том, что вам нужно знать о COM, чтобы решить 90% проблем, связанных с использованием компонентов COM.
0xd указывает на функцию, имеющую соответствующий идентификатор в файле .idl / .odl. Когда COM-объект поддерживает IDispatch, каждая функция получает номер следующим образом:
[id(1), helpstring("method Test")] HRESULT Test([in] long number);
В вашем случае функция имеет идентификатор 13 (0xd hex). Это функция, которая будет вызываться во время выполнения.
Вы не можете войти в (отладить) функцию, если у вас нет исходного кода и файлов .pdb для обеих сторон.
Если этот файл создается из MFC или из управляемого кода с помощью вызываемой оболочки во время выполнения, будет создан прокси-класс. Его имя будет довольно близко соответствовать имени интерфейса COM в оригинальном файле .idl. Это должно дать вам подсказку, откуда взялась обертка.
Есть смысл?