Delphi 的編譯指令(1): $DEFINE、$UNDEF、$IFDEF、$ELSE、$ENDI

一個程序從無到有的過程是這樣的: 編輯代碼 -> 預處理 -> 編譯(成dcu等) -> 連接(爲exe等).

什麼是預處理?
譬如 VCL 中有不少代碼是兼容 Linux 的, 在 Windows 下就須要在編譯以前預處理掉那些 for Linux 的代碼.測試



一、判斷操做系統:優化


其中的 "MSWINDOWS" 和 "LINUX" 就是 Delphi 預約義的 "條件標識符".ui


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


二、自定義條件標識符(DEFINE):spa


下面例子中自定義了條件標識符: WanYi; 標識符和定義它的指令都不區分大小寫, 但你們通常慣用大寫.
操作系統


begin  {$DEFINE WANYI}  {$IFDEF WanYi}    ShowMessage('標識符 WanYi 已定義');
  {$ELSE}    ShowMessage('標識符 WanYi 未定義');
  {$ENDIF}end;


三、取消條件標識符的定義(UNDEF):調試


begin  {$DEFINE WANYI}  {$IFDEF WANYI}     ShowMessage('確認標識符 WanYi 是否認義');
  {$ENDIF}  {$UNDEF WANYI}  {$IFDEF WANYI}     ShowMessage('再次確認標識符 WanYi 是否認義');
  {$ENDIF}end;


四、取消定義的簡單辦法:code


在 {$...} 的 $ 前面隨便加點什麼, 讓它變成 "註釋", 譬如: {.$}
it


begin  {.$DEFINE WANYI}  {$IFDEF WANYI}     ShowMessage('確認標識符 WanYi 是否認義');
  {$ENDIF}  {.$UNDEF WANYI}  {$IFDEF WANYI}     ShowMessage('再次確認標識符 WanYi 是否認義');
  {$ENDIF}end;


五、調試編譯指令時特別要注意的:io


Delphi 有個常識: 若是單元代碼沒有改變, 相應的 dcu 不會從新生成!

所以, 爲了有準確的調試結果, 執行前先用 Shift+F9 強制編譯當前工程, 而後再 Run;
強制編譯全部相關單元也能夠, 方法: Project -> Build all project.

固然修改下代碼也很方便, 譬如在代碼中打個空格再退回來.編譯



六、測試預約義的 Debug 和 Release:


當咱們當新建一個工程, Delphi 默認的是調試(Debug)狀態, 當咱們發佈軟件時應該切換到發佈(Release)狀態.
兩種狀態下編譯指令是有區別的, 在 Release 狀態下發布的 dcu 或 exe 會更小、更優化.

Debug 和 Release 的切換方法:
進入 Project Manager -> Build Configurations, 在 Debug 或 Release 上雙擊, 或從右鍵 Activate.

下面的代碼能夠檢測到這種改變, 不過要注意上面提到的 Shift+F9 或 Project -> Build all project.


begin  {$IFDEF DEBUG}    ShowMessage('調試模式');
  {$ENDIF}  {$IFDEF RELEASE}    ShowMessage('發佈模式');
  {$ENDIF}end;


七、編譯指令寫在哪?:


編譯指令能夠寫在代碼頁的任何地方, 不過在代碼的不一樣區域有時也會不一樣;

譬如: {$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 就只能寫在工程文件裏纔有效.

{$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 分別表示窗口工程和控制檯工程.
其中 {$APPTYPE GUI} 是默認的, 因此不多見到它.

它甚至能夠嵌入到代碼行當中, 譬如 ActnColorMaps 單元就有這麼一句:


begin  SystemParametersInfo(SPI_GETFLATMENU, 0, {$IFNDEF CLR}@{$ENDIF}FlatMenus, 0);end;


八、條件標識符的有效範圍:


Delphi 預約義的條件標識符都是全局的, 咱們用 {$DEFINE ...} 自定義的標識符都是局部的.

如何自定義全局的標識符呢?
Project -> Options... -> 選定 Delphi Compiler -> 點擊 Conditional defines 右邊小按鈕 -> 添加.

不過這和系統預約義的仍是有區別, 我們自定義的只能用於當前文件.

如何定義每一個文件均可以使用的標識符呢?
從 Project -> Options... 定義後, 立刻選擇左下角的 Default.

這和系統預約義的仍是有區別, 由於這隻能左右之後的文件, 管不着之前存在的文件.
如何...沒辦法了.

其餘編譯指令, 譬如在 Debug 或 Release 中的設置也都是這樣; 也就是說: 每一個文件都有相對獨立的編譯設置.

看到 Project -> Options... 立刻明白了編譯指令的設置方法有兩種:
一、使用 {$...} 在代碼中嵌入;
二、從 Project -> Options... 設置.

但在代碼中嵌入有時是不可替代的, 譬如如今討論的條件編譯.



九、編譯指令有多少?:


如今談到的還只是條件編譯, 實際應用最多的是開關編譯; 在任一代碼頁執行快捷鍵 Ctrl+O+O , 而後看看最上面...

下面列出了這些默認設置:


{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}{$MINSTACKSIZE $00004000}{$MAXSTACKSIZE $00100000}{$IMAGEBASE $00400000}{$APPTYPE GUI}{$WARN SYMBOL_DEPRECATED ON}{$WARN SYMBOL_LIBRARY ON}{$WARN SYMBOL_PLATFORM ON}{$WARN SYMBOL_EXPERIMENTAL ON}{$WARN UNIT_LIBRARY ON}{$WARN UNIT_PLATFORM ON}{$WARN UNIT_DEPRECATED ON}{$WARN UNIT_EXPERIMENTAL ON}{$WARN HRESULT_COMPAT ON}{$WARN HIDING_MEMBER ON}{$WARN HIDDEN_VIRTUAL ON}{$WARN GARBAGE ON}{$WARN BOUNDS_ERROR ON}{$WARN ZERO_NIL_COMPAT ON}{$WARN STRING_CONST_TRUNCED ON}{$WARN FOR_LOOP_VAR_VARPAR ON}{$WARN TYPED_CONST_VARPAR ON}{$WARN ASG_TO_TYPED_CONST ON}{$WARN CASE_LABEL_RANGE ON}{$WARN FOR_VARIABLE ON}{$WARN CONSTRUCTING_ABSTRACT ON}{$WARN COMPARISON_FALSE ON}{$WARN COMPARISON_TRUE ON}{$WARN COMPARING_SIGNED_UNSIGNED ON}{$WARN COMBINING_SIGNED_UNSIGNED ON}{$WARN UNSUPPORTED_CONSTRUCT ON}{$WARN FILE_OPEN ON}{$WARN FILE_OPEN_UNITSRC ON}{$WARN BAD_GLOBAL_SYMBOL ON}{$WARN DUPLICATE_CTOR_DTOR ON}{$WARN INVALID_DIRECTIVE ON}{$WARN PACKAGE_NO_LINK ON}{$WARN PACKAGED_THREADVAR ON}{$WARN IMPLICIT_IMPORT ON}{$WARN HPPEMIT_IGNORED ON}{$WARN NO_RETVAL ON}{$WARN USE_BEFORE_DEF ON}{$WARN FOR_LOOP_VAR_UNDEF ON}{$WARN UNIT_NAME_MISMATCH ON}{$WARN NO_CFG_FILE_FOUND ON}{$WARN IMPLICIT_VARIANTS ON}{$WARN UNICODE_TO_LOCALE ON}{$WARN LOCALE_TO_UNICODE ON}{$WARN IMAGEBASE_MULTIPLE ON}{$WARN SUSPICIOUS_TYPECAST ON}{$WARN PRIVATE_PROPACCESSOR ON}{$WARN UNSAFE_TYPE OFF}{$WARN UNSAFE_CODE OFF}{$WARN UNSAFE_CAST OFF}{$WARN OPTION_TRUNCATED ON}{$WARN WIDECHAR_REDUCED ON}{$WARN DUPLICATES_IGNORED ON}{$WARN UNIT_INIT_SEQ ON}{$WARN LOCAL_PINVOKE ON}{$WARN MESSAGE_DIRECTIVE ON}{$WARN TYPEINFO_IMPLICITLY_ADDED ON}{$WARN RLINK_WARNING ON}{$WARN IMPLICIT_STRING_CAST ON}{$WARN IMPLICIT_STRING_CAST_LOSS ON}{$WARN EXPLICIT_STRING_CAST OFF}{$WARN EXPLICIT_STRING_CAST_LOSS OFF}{$WARN CVT_WCHAR_TO_ACHAR OFF}{$WARN CVT_NARROWING_STRING_LOST OFF}{$WARN CVT_ACHAR_TO_WCHAR OFF}{$WARN CVT_WIDENING_STRING_LOST OFF}{$WARN XML_WHITESPACE_NOT_ALLOWED ON}{$WARN XML_UNKNOWN_ENTITY ON}{$WARN XML_INVALID_NAME_START ON}{$WARN XML_INVALID_NAME ON}{$WARN XML_EXPECTED_CHARACTER ON}{$WARN XML_CREF_NO_RESOLVE ON}{$WARN XML_NO_PARM ON}{$WARN XML_NO_MATCHING_PARM ON}
相關文章
相關標籤/搜索