程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi 的編譯指令(1): $DEFINE、$UNDEF、$IFDEF、$ELSE、$ENDIF

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

編輯:Delphi

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

  什麼是預處理?

  譬如 VCL 中有很多代碼是兼容 Linux 的, 在 Windows 下就需要在編譯之前預處理掉那些 for Linux 的代碼.

  1、判斷操作系統:

  其中的 "MSWindows" 和 "Linux" 就是 Delphi 預定義的 "條件標識符".

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

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

  下面例子中自定義了條件標識符: WanYi; 標識符和定義它的指令都不區分大小寫, 但大家一般慣用大寫.

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

  3、取消條件標識符的定義(UNDEF):

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

  4、取消定義的簡單辦法:

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

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

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

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

  因此, 為了有准確的調試結果, 執行前先用 Shift+F9 強制編譯當前工程, 然後再 Run;

  強制編譯所有相關單元也可以, 方法: Project -> Build all project.

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

  6、測試預定義的 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;

  7、編譯指令寫在哪?:

  編譯指令可以寫在代碼頁的任何地方, 不過在代碼的不同區域有時也會不同;

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

  {$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 分別表示窗口工程和控制台工程.

  其中 {$APPTYPE GUI} 是默認的, 所以很少見到它.

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

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

8、條件標識符的有效范圍:

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

  如何自定義全局的標識符呢?

  Project -> Options... -> 選定 Delphi Compiler -> 點擊 Conditional defines 右邊小按鈕 -> 添加.

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

  如何定義每個文件都可以使用的標識符呢?

  從 Project -> Options... 定義後, 馬上選擇左下角的 Default.

  這和系統預定義的還是有區別, 因為這只能左右以後的文件, 管不著以前存在的文件.

  如何...沒辦法了.

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

  看到 Project -> Options... 馬上明白了編譯指令的設置方法有兩種:

  1、使用 {$...} 在代碼中嵌入;

  2、從 Project -> Options... 設置.

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

  9、編譯指令有多少?:

  現在談到的還只是條件編譯, 實際應用最多的是開關編譯; 在任一代碼頁執行快捷鍵 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}




  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved