Почему я могу скомпилировать 64-разрядные библиотеки Delphi через runtime package, но не через исходный код?

#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). Взгляните туда.