#delphi
#delphi
Вопрос:
Мы только начинаем перенос некоторых наших проектов на 64-разрядную версию Delphi, у нас также есть пара библиотек Delphi сторонних производителей, которые мы используем. Традиционно, когда мы используем стороннюю библиотеку, мы делаем это с помощью пакета времени разработки .бпл ИЛИ мы просто поручаем компилятору скомпилировать исходный код.
Однако в 64-разрядной версии, похоже, мы должны сделать это совершенно по-другому. Если мы компилируем 64-разрядную библиотеку, нам нужно использовать DCU.
Например, у нас есть библиотека, которую нам нужно было использовать в 64-разрядной версии. Библиотека поддерживает 64-разрядную версию. Чтобы заставить это работать, мне пришлось скомпилировать runtime package как 64-разрядный, а затем указать компилятору на выводимые 64-разрядные файлы DCU. Когда я пытаюсь скомпилировать библиотеку из исходного кода как 64-разрядную, мы получаем всевозможные ошибки.
Итак, мой вопрос в основном таков: почему / как мы можем просто скомпилировать исходный код через runtime packages в 64-разрядной версии, но когда мы пытаемся скомпилировать только исходный код в 64-разрядной версии, мы получаем ошибки?
Для дополнительной иллюстрации на всякий случай, если это было непонятно:
A. Поместите все исходные файлы по пути поиска. Скомпилируйте программу как 64-разрядную. ОШИБКИ.
B. Откройте предоставленный runtime .dproj из сторонней библиотеки. Скомпилируйте библиотеку runtime как 64-разрядную. Поместите выведенный 64-разрядный DCU в путь поиска. Скомпилируйте программу. Работает нормально.
Спасибо
Редактировать: я собираюсь быть гораздо более конкретным, потому что, похоже, мне не удалось передать то, что я пытаюсь спросить здесь.
Мы используем Clever Internet Suite 9.1 для Delphi. Мы НЕ используем пакет времени разработки при компиляции в 32-разрядной версии. Мы ссылаемся непосредственно на исходный код через путь поиска Delphi. Это работает нормально.
Когда я меняю свое приложение на 64-разрядное, мы получаем эту ошибку:
[Ошибка dcc64] clSocket.pas (1971): E2089 недопустимый набор типов
Пример кода-нарушителя (слегка изменен):
procedure cldostuff.WndProc(var Message: TMessage);
begin
if (Message.Msg = cl_const)
and (clSpecialType(Message).LookupHandle = FLookupHandle) then
begin
syncerror:= clSpecialType(Message).syncerror;
SetEvent(FCompleted);
end;
end;
Ошибка связана с приведением TMessage. Я понимаю, почему TMessage может вызвать ошибку. Меня не беспокоит ошибка.
Мне любопытно, КАК работает компиляция через «пакет», но не в DCU. По-видимому, я неправильно использовал терминологию «Runtime package». Я опубликую именно то, что умные разработчики рассказали мне о том, как использовать в 64-разрядной версии.
Clever Internet Suite полностью поддерживает 64-разрядную платформу. Установщик включает двоичные файлы как для 32-разрядных, так и для 64-разрядных версий. Кроме того, если вы хотите повторно скомпилировать библиотеку, вам нужно переключить параметр платформы в файле clinetsuite_x.dproj и перекомпилировать его (где _x зависит от вашей версии Delphi, например, в случае Delphi 10.3 Rio файл проекта будет clinetsuite_103.dproj).
Итак, я делаю именно это. Я открываю этот файл .Dproj и компилирую его. Как только я это сделаю, создается папка Win64 / Output, в которой содержатся ВСЕ dcu библиотеки. Я могу ссылаться на это и отлично работать в win64 bit.
Мои вопросы в том, ПОЧЕМУ это работает, когда я компилирую через «Предоставленный файл .dproj», но не когда я компилирую через исходный код.
Надеюсь, я лучше сформулировал то, о чем спрашиваю.
Комментарии:
1. Не существует такой вещи, как компилировать исходный код из пакетов времени выполнения . Пакеты выполнения содержат скомпилированный исполняемый код (например, DLL), и ничего из них не компилируется в ваше приложение, кроме ссылки на код в пакете. Часть, которая компилируется в ваше приложение, берется откуда-то еще, кроме пакета, которым может быть файл .dcu или .dcp. Нет проблем с компиляцией 64-разрядного приложения для использования 64-разрядных пакетов. Скомпилируйте 64-разрядную версию пакета, а затем скомпилируйте приложение, которое использует его как 64-разрядную.
2. У меня работает. Что вы делаете по-другому?
3. Возможно, в
{$DEFINE ...}
файле библиотеки есть некоторые символы, определенные с помощью.dproj
для условной компиляции исходных файлов библиотеки..4. Ну, edt помогает. Ошибка компилятора полезна. Проблема будет в параметрах компилятора. Вероятно, для этого кода требуется,
{A }
где определен типclSpecialType
. Он подберет его из файла package dproj, но не из файла dproj вашего lr code. На самом деле параметры компилятора должны быть реализованы с помощью файла, включаемого в библиотеку, который включают все файлы в библиотеке. Но эта библиотека, вероятно, неаккуратна в этом отношении.5. Черт возьми, это означает, что библиотека, вероятно, не установила никаких соответствующих настроек в файлах .pas. Это должно было быть сделано проще и менее зависимым от внешних настроек.
Ответ №1:
Эта ошибка компилятора обычно вызывается приведением типов между двумя типами значений разного размера. Если код работает в некоторых сценариях компиляции, но не в других, то очевидный вывод заключается в том, что параметры выравнивания записей в этих сценариях различаются.
Скорее всего, файл package dproj определяет выровненные записи, т.е. {$ALIGN ON}
. Но ваш проект этого не делает. Возможно, он использует упакованное выравнивание, {$ALIGN 1}
.
Убедитесь, что все модули в библиотеке скомпилированы с теми же параметрами, что указаны в файле package dproj. Обычно это делается библиотекой, предоставляющей включаемый файл, в котором указаны желаемые параметры, а затем включаемый файл включается во все модули. Это изолирует код от параметров компилятора, указанных в файле dproj хоста, которые несовместимы с теми, которые требуются коду.
Вы можете добавить такой общий включаемый файл, поскольку у вас есть исходный код. В долгосрочной перспективе вам следует попросить разработчиков библиотеки сделать их код автономным и не требовать внешней спецификации критических параметров компилятора.
Комментарии:
1. Я бы написал «вероятно» вместо «обычно», но в противном случае, согласен.
2. В исходном коде dproj действительно есть это: {$ ALIGN 8} Я не хочу публиковать многое из их исходного кода, потому что я не хочу нарушать какие-либо лицензии или что-либо еще. Но у них также есть файл .inc, который находится вместе с файлами .pas, на которые я ссылаюсь. Итак, нужно ли мне поместить это {$ ALIGN 8} куда-нибудь в .inc файл или .pas файлы?
3. @rudy Нет, я обычно использую намеренно. Идиома используется, чтобы предложить наиболее распространенную практику библиотек. Вероятно, это было бы использовано, когда речь идет об этом конкретном.
4. Я ожидал бы увидеть выравнивание, указанное в файле inc, поскольку оно имеет решающее значение для смысла большого количества кода.
5. @D.D: {$ALIGN 8} также используется по умолчанию для Win32 и Win64. Но если нет включаемого файла, который включен (почти) в каждый исходный файл, тогда будут использоваться настройки в параметрах проекта (в IDE и dproj). Взгляните туда.