Нарушение прав доступа после GetInterface/QueryInterface в Delphi

Во-первых, я очень новичок в Delphi и COM, но я должен создать приложение COM в Delphi. Я прочитал много статей и заметок в интернете, но COM и COM в Delphi мне до сих пор не понятны.

Мои источники - http://www.everfall.com/paste/id.php?wisdn8hyhzkt (около 80 строк).

Я пытаюсь сделать COM-интерфейс и класс Impl - это работает, если я вызываю интерфейсный метод из Delphi (я создаю объект impl через TestClient.Create), но если я пытаюсь создать объект из внешнего мира (из Java, через com4j)) мое приложение упало со следующим исключением:

Project Kernel.exe raised exception class $C0000005 with 
message 'access violation at 0x00000002: read of address 0x00000002'.

Если я устанавливаю точку останова в QueryInterface - она ​​ломается, но когда я выхожу из функции - все вылетает.

Что я делаю не так? Что мне еще не хватает? Что я могу / должен прочитать о COM (в Delphi), чтобы избежать таких глупых вопросов?

3 ответа

Решение

Я сделал DLL с COM с нуля и

  1. Я использую DllRegisterServer - он дал мне возможность контролировать регистрацию сервера (через TComObjectFactory.RegisterClassObject в моей первой попытке)
  2. Я удаляю QueryInterface из моего TestComImpl
  3. Com4j поддерживает только модель потоков STA (Apartment) (я полагаю, что RegisterClassObject использует MTA)
  4. Так что, если класс зарегистрирован как квартира (STA) или оба - com4j может создавать экземпляры.

Спасибо всем за помощь!

Нет необходимости реализовывать IUnkown.QueryInterface самостоятельно. Удалите этот метод из TestComImpl и позвольте TComObject обработать его. Также обязательно предоставьте интерфейсу ITestCom GUID.

Если сбой происходит после возврата QueryInterface, я бы поставил точку останова в приложении Java, когда оно вызывает QueryInterface, и посмотрю, что он пытается сделать дальше. Это даст вам представление о том, где искать.

Ваш комментарий, кажется, подтверждает это. Он вызывает QueryInterface, возвращает результат, который говорит, что этот интерфейс хорош, и пытается использовать его для чего-то, что немедленно ломается. Но если вы закомментируете код, который говорит о том, что интерфейс хорош, он в конечном итоге не пытается использовать интерфейс, и ничего не ломается.

Если вы не знакомы с Delphi, нарушение доступа обычно означает разыменование нулевого указателя. Здесь говорится, что указатель вашей инструкции находится в ячейке памяти 0x000002. Это, вероятно, означает, что вы каким-то образом пытались вызвать виртуальный метод (или интерфейсный метод) для объекта, который еще не был создан.

Надеюсь, это поможет!

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