Delphi 函數是程式碼複用的基本單元。本文涵蓋函數定義語法、返回值處理、調用約定、前向聲明、外部連結(DLL/Obj)、函數重載等核心知識,並對比方法與獨立函數的異同,提供完整可編譯範例。
function FunctionName(ParameterList): ReturnType; Directives;
LocalDeclarations;
begin
Statements;
end;
{ 寫法 1:賦值給函數名 }
function WF: Integer;
begin
WF := 17;
end;
{ 寫法 2:使用 Result 隱含變數(推薦) }
function WF: Integer;
begin
Result := 17;
end;
{ 寫法 3:混合使用(Result 可多次賦值) }
function MyFunction: Integer;
begin
MyFunction := 5;
Result := Result * 2; // Result = 10
MyFunction := Result + 1; // 返回 11
end;
建議:統一使用 Result,可讀性最好,且支援提前退出(Exit(Result))。
| 約定 | 參數壓棧順序 | 棧清理者 | 寄存器傳參 | 典型用途 |
|---|---|---|---|---|
| register | 左→右 | 被調用者 | 是(前 3 個) | Delphi 預設,效能最佳 |
| pascal | 左→右 | 被調用者 | 否 | 舊版 Pascal 相容 |
| cdecl | 右→左 | 調用者 | 否 | C/C++、可變參數 |
| stdcall | 右→左 | 被調用者 | 否 | Win32 API、COM |
| safecall | 右→左 | 被調用者 | 否 | COM、自動 HRESULT 轉異常 |
// 範例
function MyFunction(X, Y: Real): Real; cdecl;
function WinAPICall(Param: Integer): Integer; stdcall; external 'user32.dll' name 'RealFunctionName';
function Calculate(X, Y: Integer): Real; forward; // 僅聲明
// ... 其他代碼 ...
function Calculate; // 實現時可省略參數列表
// 區域聲明
begin
// 實現
end;
{$L BLOCK.OBJ}
procedure MoveWord(var Source, Dest; Count: Integer); external;
procedure FillWord(var Dest; Data: Integer; Count: Integer); external;
function SomeFunction(S: string): string; external 'strlib.dll';
function MessageBox(HWnd: Integer; Text, Caption: PChar; Flags: Integer): Integer;
stdcall; external 'user32.dll' name 'MessageBoxA'; // 指定實際導出名
external 'dllname':延遲載入 DLL,首次呼叫時載入。name 'exportname':導出名與 Delphi 名稱不同時使用。PChar 或 WideString(BSTR),避免記憶體管理器不一致導致崩潰。function Divide(X, Y: Real): Real; overload;
begin
Result := X / Y;
end;
function Divide(X, Y: Integer): Integer; overload;
begin
Result := X div Y;
end;
// 呼叫
var
R1: Real; I1: Integer;
begin
R1 := Divide(10.0, 3.0); // 3.333...
I1 := Divide(10, 3); // 3
end;
| 特性 | 獨立函數 | 方法 |
|---|---|---|
| 聲明位置 | 單元介面/實現區 | 類型定義內部 |
| 隱含參數 | 無 | Self(實例/類別參考) |
| 存取權限 | 單元可見性 | private/protected/public/published |
| 多態 | 不支援 | 支援 virtual/override |
| 重載 | 支援 | 支援 |