Delphi 编译指令的使用方法

来源:互联网 发布:五冠淘宝店铺年收入 编辑:程序博客网 时间:2024/05/07 00:28
 一个程序从无到有的过程如下:
 编辑代码 -> 预处理 -> 编译(成dcu等) -> 链接(为exe等).

 

1.编译指令原理介绍

         一条编译指令实际上是一个标志符(编译器所能识别的标志符),且有其固定的语法。编译器根据不同的指令按不同的方式编译程序。

编译指令的开始字符是“ $“ ,它总是出现在 “{“符号之后,$之后为编译指令的实际部分,可以是一个或多个字符(根据指令的不同而
定),在指令后还可以包含一个或多个需要的参数。一个编译指令的结束符为“}”。 例如:{$WARN SYMBOL_DEPRECATED ON}

 2.Delphi编译指令的使用范围:

         你可以将一个编译指令放在程序的任何位置,甚至可以嵌入到代码行当中(在实参中可以使用{$IFNDEF CLR}@{$ENDIF}FlatMenus
这样一段代码作为参数), 但有些指令只能写在特定的地方。例如:{$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 就只能写在工程文件里才

有效. {$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 分别表示窗口工程和控制台工程. 其中 {$APPTYPE GUI} 是默认的, 所以很少见到它。

 

全局编译指令:  影响全部的编译内容,它必须在放在程序和单元声明之前。
局部编译指令:  仅影响局部的编译内容,它的影响范围是,直至下一个最近的编译指令。它可以放在程序的任意位置。
开关编译指令:  可以组合成一个简单的编译指令组,中间用逗号分开,但不能有空格。例如:{$B+,R-,S-}  //注意:不能有空格

Delphi 预定义的条件标识符都是全局的,

自定义局部的标识符:用 {$DEFINE ...} 自定义的标识符都是局部的.
自定义全局的标识符:Project -> Options... -> 选定 Delphi Compiler -> 点Conditional defines 右边小按钮 -> 添加.

3.Delphi编译指令共有三种:

              1>.开关编译指令:有 on 、off 两种转换状态;

              2>.参数编译指令:通过参数指定影响的的内容,参数可以为文件名或内存大小

              3>.条件编译指令: 指定如何编译特定的区域段
      注意:所有的编译指令(除开关编译指令外)在名字和参数之间至少应有一个空格。

1>.开关编译指令
        开关编译指令地特点是它有 on 、off 两种转换状态。对于单字符版本,你可以在编译指令后添加 "+"或“-”。
对于长字符版本,你可以在编译指令后添加 “on”或“off”。
        实际应用最多的是开关编译; 在任一代码页执行快捷键 Ctrl+O+O , 就会显示所有的开关编译指令在当前页的最上面。


2>.参数编译指令
参数编译指令通过参数指定影响的的内容,参数可以为文件名或内存大小等。

$R Filename :
            这个编译指令是最为常用的编译指令,他是资源文件编译指令,用于指定连接到执行文件和库的资源文件,

例如在工程文件(.dpr)中会有{$R *.RES}的编译指令,表明把后缀为 .RES的与工程文件同名的资源文件连接入执行文件,

也可以指定一个资源文件,资源文件的使用对于编写Windows程序来说是很重要的基础。

 $I Filename :

             这个编译指令功能类似于C语言的#Include , 用于指定编译时包括的文件。

 

3>.条件编译指令
条件编译指令指定的条件如何编译特定的区域段。也就是如果满足某个条件,
则按照一种方式编译,否则按另一种方式编译。

条件编译指令含义:

$DEFINE : 用于定义一个条件符号,一旦定义,条件符号就为真

$IFDEF :  对条件符号进行判断,为真则编译源文件

$ELSE:  与$IFDEF配合使用,如果$IFDEF条件为假,则只对源文件$ELSE后一小部分进行编译

$IFNDEF:  对条件符号进行判断,为假则编译源文件

$IFOPT : 根据编译开关状态,对源文件编译

$UNDEF : 撤消以前的条件符号定义

$ENDIF : 结束一个以$IF开始的条件段

这些条件编译指令是非常有用的。例如,可以通过开关的状态来控制编译:

注意:Delphi 有个常识: 如果单元代码没有改变, 相应的 dcu 不会重新生成。所以使用编译设置对话框设置一些指令,可能不

会引起dcu重新生成的,此时可以使用Shirt+F9强制编译,或者修改一下代码(譬如在代码中打个空格再退回来)。

所有的编译指令(除开关编译指令外)在名字和参数之间至少应有一个空格。
例如:
{$B+}
{$STACKCHECKS ON}
{$R- Turn off range checking}
{$I TYPES.INC}
{$M 32768,4096}
{$DEFINE Debug}
{$IFDEF Debug}
{$ENDIF}

 

3.编译指令的使用方法(高级编译指令):


1>.什么是预处理(编译指令的作用)?
譬如 VCL 中有很多代码是兼容 Linux 的, 在 Windows 下就需要在编译之前预处理掉那些 for Linux 的代码.例如:判断操作系统: 其中的 "MSWINDOWS" 和 "LINUX" 就是 Delphi 预定义的 "条件标识符".

begin
{$IFDEF MSWINDOWS}
    ShowMessage('Windows');
{$ENDIF}
{$IFDEF LINUX}
    ShowMessage('Linux');
{$ENDIF}
end;


2>. $IFDEF 等同于 $IF DEFINED(...) : 它们的结束分别是: $ENDIF、$IFEND; 例子中的 VER200 是 Delphi 2009 的标识.

begin

  {$IFDEF VER200}

    ShowMessage('这是 Delphi 2009');

  {$ENDIF}

  {$IF DEFINED(VER200)}

    ShowMessage('这是 Delphi 2009');

  {$IFEND}

end;
3>. $IFNDEF 等同于 $IF NOT DEFINED(...) : 它们的结束分别是: $ENDIF、$IFEND; 例子中的 VER150 是 Delphi 7 的标识.

begin

  {$IFNDEF VER150}

    ShowMessage('这不是 Delphi 7');

  {$ENDIF}

  {$IF NOT DEFINED(VER150)}

    ShowMessage('这不是 Delphi 7');

  {$IFEND}

end;

4>. 可以使用 or 和 and:

begin

  {$DEFINE AAA}

  {$DEFINE BBB}

  {$IF DEFINED(AAA) OR DEFINED(BBB)}

    ShowMessage('条件标识符 AAA 和 BBB 其中一个定义了');

  {$IFEND}

  {$IF DEFINED(AAA) AND DEFINED(BBB)}

    ShowMessage('条件标识符 AAA 和 BBB 都定义了');

  {$IFEND}

end;
5>. 可以使用 System 单元里的常量: 我测试了 System 单元里的很多常量都没问题.

begin

  ShowMessage(FloatToStr(CompilerVersion)); {在 Delphi 2009 中, CompilerVersion = 20.0}

  {$IF CompilerVersion >= 17.0}

    ShowMessage('这是 Delphi 2005 或以上的版本');

  {$IFEND}

end;

6>. 使用 $IFOPT 判断编译开关: Delphi 挺好玩, 26个字母分别安排成不同的开关指令(用 Ctrl+o+o 查看, 当然开关指令不止这些);
$IFOPT 可以判断这些指令是否打开.
这个指令不是很常用, 我看了一下 2009 的 VCL 源码, 总共才用了 6 次.

begin

  {$IFOPT B+}

    ShowMessage('指令 B 已打开');

  {$ELSE}

    ShowMessage('指令 B 已关闭');

  {$ENDIF}

  {$B+}

  {$IFOPT B+}

    ShowMessage('Ok!');

  {$ENDIF}

end;

原创粉丝点击