Нарушение прав доступа после 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 с нуля и
- Я использую DllRegisterServer - он дал мне возможность контролировать регистрацию сервера (через TComObjectFactory.RegisterClassObject в моей первой попытке)
- Я удаляю QueryInterface из моего TestComImpl
- Com4j поддерживает только модель потоков STA (Apartment) (я полагаю, что RegisterClassObject использует MTA)
- Так что, если класс зарегистрирован как квартира (STA) или оба - com4j может создавать экземпляры.
Спасибо всем за помощь!
Нет необходимости реализовывать IUnkown.QueryInterface самостоятельно. Удалите этот метод из TestComImpl и позвольте TComObject обработать его. Также обязательно предоставьте интерфейсу ITestCom GUID.
Если сбой происходит после возврата QueryInterface, я бы поставил точку останова в приложении Java, когда оно вызывает QueryInterface, и посмотрю, что он пытается сделать дальше. Это даст вам представление о том, где искать.
Ваш комментарий, кажется, подтверждает это. Он вызывает QueryInterface, возвращает результат, который говорит, что этот интерфейс хорош, и пытается использовать его для чего-то, что немедленно ломается. Но если вы закомментируете код, который говорит о том, что интерфейс хорош, он в конечном итоге не пытается использовать интерфейс, и ничего не ломается.
Если вы не знакомы с Delphi, нарушение доступа обычно означает разыменование нулевого указателя. Здесь говорится, что указатель вашей инструкции находится в ячейке памяти 0x000002. Это, вероятно, означает, что вы каким-то образом пытались вызвать виртуальный метод (или интерфейсный метод) для объекта, который еще не был создан.
Надеюсь, это поможет!