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...

Другие вопросы по тегам