Нарушение прав доступа после GetInterface / QueryInterface в Delphi - PullRequest
2 голосов
/ 23 апреля 2010

Во-первых, я очень новичок в 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 ]

2 голосов
/ 23 апреля 2010

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

0 голосов
/ 26 апреля 2010

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

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

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

0 голосов
/ 23 апреля 2010

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

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

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

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

...