首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

Delphi DLL 開發完整範例:從專案建立到動態/靜態載入呼叫

     編輯:關於SqlServer

DLL 專案結構

testDll.dpr          -- 專案檔,exports 匯出函數
DLLFrm.pas/dfm       -- 表單單元,含 TMonthCalendar 日期選擇元件
FtestDll.pas/dfm     -- 測試主程式,動態/靜態載入示範

核心程式碼解析

1. DLL 專案檔

library testDll;
uses SysUtils, Classes, DLLFrm in 'DLLFrm.pas' {frmDLL};
{$R *.res}
exports
  ShowDLLModalForm, ShowDLLForm, ShowCalendar;  -- 標準呼叫慣例
begin
end.

2. 表單單元 - 匯出函數定義

procedure ShowDLLModalForm(aHandle: THandle); stdcall;
procedure ShowDLLForm(aHandle: THandle); stdcall;
function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime; stdcall;

3. 實作細節

  • 模態顯示:Application.Handle := aHandle; Form.ShowModal; 確保父視窗停用
  • 非模態顯示:Form.Show; 需自行管理表單釋放
  • 日期回傳:ShowCalendar 依 ModalResult 回傳選取日期或預設值
  • 記憶體管理:ShareMem 機制(若傳遞 String 需加入),範例採用 PChar/ShortString 避免依賴 BORLNDMM.DLL

4. 測試程式 - 動態載入

// FormCreate
DLLHandle := LoadLibrary('testDll.dll');
if DLLHandle = 0 then RaiseLastOSError;

// 按鈕點擊 - 取得函數位址並呼叫
@ShowDLLForm := GetProcAddress(DLLHandle, 'ShowDLLModalForm');
if @ShowDLLForm = nil then RaiseLastOSError;
ShowDLLForm(Application.Handle);

// FormDestroy
if DLLHandle <> 0 then FreeLibrary(DLLHandle);

5. 靜態載入替代方案

// 宣告外部函數
procedure ShowDLLModalForm(aHandle: THandle); stdcall external 'testDll.dll';
// 直接呼叫
ShowDLLModalForm(Application.Handle);

關鍵最佳實務

  1. stdcall:WinAPI 標準呼叫慣例,確保跨語言相容
  2. Application.Handle 傳遞:DLL 內 Application.Handle := aHandle 關鍵,否則模態視窗不會正確停用父視窗
  3. 例外處理:DLL 內部例外不跨越邊界,需自行 try...except 包裹並回傳錯誤碼
  4. 資源釋放:FormDestroy 必呼叫 FreeLibrary,避免模組洩漏
  5. 字串傳遞:優先使用 PAnsiChar/PWideChar,避免 ShareMem 部署複雜度

常見坑點

  • DLL 與 EXE 使用不同版本的 RTL/VCL → 記憶體管理衝突
  • 未正確傳遞 Application.Handle 導致模態視窗行為異常
  • 動態載入未檢查 GetProcAddress 回傳值直接呼叫 → AV
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved