Delphi条件编译中的uses子句

时间:2014-10-01 23:31:15

标签: delphi delphi-2010 conditional-compilation delphi-xe7

我正在尝试修改我的Delphi 2010代码以在XE7中编译(并希望保留在2010年编译它的能力)。因此,在我的mainform的单元中,我添加了条件指令。以下工作在2010年运作良好

uses 
  {$IF CompilerVersion >= 24}System.Actions, {$ELSE}Actnlist,{$IFEND}
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,  Dialogs;

但是XE7会在末尾自动添加System.Actions以创建一个uses子句,该子句现在已经将System.Actions声明了两次(见下文),并给出错误消息[dcc32 Error] MyForm.pas(10): E2004 Identifier redeclared: 'System.Actions'。为什么XE7不接受条件指令中的单位?

uses 
  {$IF CompilerVersion >= 24}System.Actions, {$ELSE}Actnlist,{$IFEND}
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,  Dialogs,
  System.Actions; // <- automatically added

4 个答案:

答案 0 :(得分:13)

正如Ken所说,接口uses子句将由IDE修改,实现这一过程的过程有点不复杂(正如您所发现的那样)。同样的问题会影响项目使用条款。不幸的是,在Form / DataModule使用子句的情况下,这很难避免。

您可以使用单位别名(请参阅David Heffernan的回答),但需要注意的是,如果您为IDE希望添加的单元创建别名,那么IDE仍将添加对所需单元的引用,因为它不会将别名识别为标识所需单元。别名到系统单元将避免这种情况,因为它已经(隐含地)被每个单元使用。

另一种方法是从您的使用列表中删除所有此类条件,然后根据需要创建占位符单元,以便您希望在项目中使用的不同编译器可以通过列表中的单个使用列表满足每个IDE都需要坚持(IDE不会从使用列表中删除未使用的单元,这通常是一种抱怨,但在这种情况下实际上有助于解决您的问题)。

在这种情况下,在您的Delphi 2010项目中创建一个空的操作单元:

 unit Actions;
 interface
 implementation
 end.

您当然需要确保该单元在项目的XE7版本的项目路径中

实现这一目标的一种方法是确保空的 Actions.pas 单元未在DPR使用列表中明确列出,但放置在项目源的子文件夹中(例如&#39 ;占位符&#39)。然后,您可以将此子文件夹添加到Delphi 2010版本的项目搜索路径中,但不能添加到XE7版本中:

 \Project Folder

     project2010.dpr
     project2010.dproj
     projectXE7.dpr
     projectXE7.dproj

     \placeholders
          Actions.pas

如果您发现每个不同版本都需要占位符,则需要单独的占位符文件夹。您可以创建更多版本特定的子文件夹,例如:

     \placeholders
          \2010
               Actions.pas
          \XE7
               D2010UnitNotPresentInXE7.pas

从创建自动/自我记录组织的角度来看,这种结构可能是明智的。

请注意,这仅用于处理表单接口部分的使用子句中的单元引用(或框架等)。在非可视单元或实现部分中,IDE不会干扰,因此条件编译指令不会出现任何问题。

答案 1 :(得分:8)

解决此问题的最简单方法是在Delphi 2010项目中添加unit alias。您需要为不同的Delphi版本使用不同的.dproj文件,但无论如何都需要这样做。

在Delphi 2010项目的单位别名设置中添加:

Actions=System

我使用System作为别名目标,因为System单位自动包含在每个Delphi单元中,因此别名包含是良性的。这是我能想到的最简单的方法,使编译器有效地忽略uses子句中的条目。

然后你可以像这样声明你的uses子句:

uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  Actions, Actnlist;

这将在Delphi 2010中正常编译,因为别名处理会将Actions映射到System。在XE7中你也很好,因为没有别名,并且IDE对Actions单元的存在感到满意,因此没有强迫修改uses子句。

答案 2 :(得分:1)

会出现问题吗?
{$IF CompilerVersion < 24}Actnlist,{$IFEND}

或者这是一个学术论点吗?

...编

然后在2010编译路径中添加一个不包含任何内容的虚拟System.Actions.dcu

我认为IDE会坚持插入uses ... System.Actions,2010有它想要的东西,XE7有它想要的东西。

但是我没有XE7所以我无法测试它。

答案 3 :(得分:1)

我们有同样的问题...... 最简单的方法是这样做:

{$IF CompilerVersion < 24}{$ELSE}System.Actions,{$IFEND}
{$IF CompilerVersion >= 24}{$ELSE}Actnlist,{$IFEND}

如果您在旧IDE中打开文件,则可能会看到错误,其中显示“单元X”未找到,但它将正常编译并且不会执行自动添加。 看起来不太好,但效果很好......

亲切的问候,

贝恩德