COM-сервер: ESP не сохраняется через вызов функции при вызове метода интерфейса
Я в процессе реализации COM-сервера в EXE-файл. Если быть точным, я добавляю интерфейс COM в существующее приложение. с конечной целью автоматизации приложения.
Первый компонент и интерфейс (пока с одним методом) в основном на месте. Я могу встроить внутрипроцессный сервер в DLL и успешно получить указатель на интерфейс и вызвать метод. Это было сделано в качестве первого шага, так как я только учусь. Мне не понадобится DLL позже; это просто служит подтверждением концепции, что мой компонент и интерфейс в основном в порядке.
Затем я создал внепроцессный сервер в EXE. Я дошел до того, что могу позвонить CoCreateInstance()
с клиента, и EXE запускается, регистрирует свою фабрику, и фабрика создает экземпляр компонента. CoCreateInstance
возвращает S_OK, и клиент получает указатель на интерфейс, который не равен NULL.
Проблема возникает, когда я вызываю метод интерфейса.
- Во-первых, точка останова в методе не достигнута (да, это в другом процессе, но я также отлаживаю сервер. Другие точки останова на сервере работают нормально).
- Во-вторых, клиент сообщает
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
,
Я абсолютно осознаю, что методы в интерфейсе COM должны использовать__stdcall
и я проверил несколько раз, что это не пропало. Кроме того, реализация компонента (C++) происходит от интерфейса, сгенерированного MIDL. Таким образом, заголовочный файл интерфейса имеет правильное соглашение о вызовах, и если заголовочный файл компонента не имеет, компилятор будет жаловаться на различия в переопределении.
Поскольку точка останова даже не достигнута, мое внутреннее чувство состоит в том, что что-то в корне не так с вызовом локальной процедуры, как это было неправильно установлено в vtbl. У кого-нибудь есть предположение, что может быть причиной наблюдаемого поведения? Любые советы о том, как отладить код прокси / заглушки?
РЕДАКТИРОВАТЬ:
В ответ на WhozCraig вот файл IDL:
import "unknwn.idl";
// Interface IMyApp1
[
object,
uuid(440EA043-DF6D-4df9-963D-7660BBA829EF),
helpstring("IMyApp1 Interface"),
pointer_default(unique)
]
interface IMyApp1: IUnknown
{
HRESULT ShowAboutBox(void);
}
1 ответ
Я нашел проблему. Это довольно неловкая ошибка, но интересно знать, что она приводит к наблюдаемому эффекту, поэтому я опубликую ее здесь на случай, если у кого-то еще возникнет такая же проблема.
Клиент делал
HdResult = CoCreateInstance(
sClassIdApp,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IUnknown, // Oops...
(void**) &pInterface);
pInterface->ShowAboutBox();
вместо
HdResult = CoCreateInstance(
sClassIdApp,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMyApp1,
(void**) &pInterface);
pInterface->ShowAboutBox();
Duh...