один и тот же класс используется в двух отдельных библиотеках не совместимы? - PullRequest
2 голосов
/ 09 апреля 2010

Сегодня пришло любопытное событие, которое заставило меня задуматься о том, как на самом деле работает объектная модель в Delphi.

Корпус:

Мы импортировали службу SOAP, которая предоставляет несколько методов, принимая объекты в качестве параметров. Delphi генерирует классы / интерфейсы, которые мы используем для связи с сервисом soap, и все объекты, используемые в качестве параметров, наследуются от TRemotable.

По разным причинам мы поместили всю связь с сервисом мыла в dll.

Затем мы попытались создать объекты, которые должны быть отправлены в основной исполняемый файл, и передать их в библиотеку для сериализации и отправки.

Теперь это не сработало, но дало исключение, которого я не ожидал.

В нем сказано, что объект, который мы пытаемся отправить в сервис мыла, должен наследоваться от TRemotable, но это так. Изучив объект, мы увидим, что класс является импортированным классом из wsdl и что родительский класс действительно TRemotable.

Сборка с пакетами решает эту проблему.

Вопрос:

Это так, что класс, определенный в исходном файле, совместно используемый двумя библиотеками, заканчивается во время выполнения как разные классы? Если так, то почему?

Насколько я знаю, нормально передавать объекты между библиотеками. Как тогда обеспечивается строгая типизация и в какой степени экземпляры объектов будут совместимы друг с другом?

Ответы [ 2 ]

3 голосов
/ 09 апреля 2010

Да, один и тот же класс в разных библиотеках отличается. Классы в каждой DLL будут загружены во время выполнения и будут указывать на различную память, поэтому A.ClassType = B.ClassType не удастся, даже для тех же исходных файлов. Вы по-прежнему можете передавать объекты, и они будут работать правильно, за исключением случаев, когда в этом случае используются «is» или «as» для сравнения самих классов. Строгая типизация обеспечивается только в том случае, если компилятор предполагает, что классы совпадают при компиляции DLL и основного приложения. Нет защиты от загрузки DLL с одной версией объекта и более новым приложением, пытающимся использовать объявление измененного объекта. Если вы хотите, вам нужно использовать пакеты.

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

Вы можете попробовать передать параметр в виде объекта TObject и с любого конца привести его в качестве TRemotable.Я не пробовал этот конкретный случай, но я знаю, что передал TObject в подобную DLL.У меня также есть аналогичная DLL для SOAP, и в моем случае это не будет работать, так как моя SOAP DLL скомпилирована с библиотеками SOAP D2007 и по сложным / устаревшим причинам, остальная часть приложения - D2005.

...