首页 > 解决方案 > 为什么我可以通过运行时包编译64位Delphi库而不是通过源代码?

问题描述

我们刚刚开始在 Delphi 中将我们的一些项目迁移到 64 位,我们还有几个正在使用的 3rd 方 Delphi 库。传统上,当我们使用 3rd 方库时,我们会使用设计时包 .bpl 或者我们只是让编译器编译源代码。

但是,在 64 位中,我们似乎必须完全不同。如果我们正在编译一个 64 位库,我们需要使用 DCU。

例如,我们有一个需要在 64 位中使用的库。该库支持 64 位。为了让它工作,我必须将运行时包编译为 64 位,然后将编译器指向输出的 64 位 DCU 文件。当我尝试将库从源代码编译为 64 位时,我们会遇到各种错误。

所以我的问题基本上是:为什么/我们如何通过运行时包编译源代码 64 位就好了,但是当我们尝试编译为 64 位源代码时会出错?

为了进一步说明以防万一不清楚:

A. 将所有源文件放在搜索路径上。将程序编译为 64 位。错误。

B. 从 3rd 方库打开提供的运行时 .dproj。将运行时库编译为 64 位。将输出的 64 位 DCU 放在搜索路径上。编译程序。工作正常。

谢谢

编辑:我将更加具体,因为我似乎未能传达我在这里想要问的内容。

我们正在为 Delphi 使用 Clever Internet Suite 9.1。在 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 中却没有。显然我误用了“运行时包”的术语。我将准确地发布聪明的开发人员告诉我的关于如何在 64 位中使用的内容。

Clever Internet Suite 完全支持 64 位平台。安装程序包括 32 位和 64 位的二进制文件。此外,如果你想重新编译库,你需要在 clinesuite_x.dproj 文件中切换平台选项,然后重新编译它(其中 _x 取决于你的 Delphi 版本,例如,在 Delphi 10.3 Rio 的情况下,项目文件将是 clinesuite_103.dproj)。

所以我就是这么做的。我打开那个 .Dproj 文件并编译它。一旦我这样做了,它就会创建一个 Win64/Output 文件夹,其中包含库的所有 dcus。我可以链接到它并在win64位下工作就好了。

我的问题是为什么当我通过“提供的 .dproj 文件”编译时它会起作用,但当我通过源代码编译时它不起作用。

希望我在表达我的要求方面做得更好。

标签: delphi

解决方案


该编译器错误通常是由两个不同大小的值类型之间的类型转换引起的。如果代码在某些编译场景中有效,但在其他场景中无效,那么显而易见的结论是记录对齐选项在这些场景中不同。

包 dproj 文件很可能定义了对齐的记录,即{$ALIGN ON}. 但你的项目没有。也许它使用打包对齐,{$ALIGN 1}.

确保库中的所有单元都使用与包 dproj 文件中指定的相同选项进行编译。通常,这是由库提供的包含文件完成的,该文件指定所需的选项,然后包含文件包含在所有单元中。这将代码与主机 dproj 文件中指定的编译器选项隔离开来,这些编译器选项与代码所需的选项不兼容。

你可以添加这样一个常见的包含文件,因为你有源。从长远来看,您应该要求库的开发人员使他们的代码独立,并且不需要关键编译器选项的外部规范。


推荐阅读