DLL 动态链接与资源嵌入实践
静态绑定调用系统函数
在 Delphi 中,可通过 external 关键字直接声明并调用 DLL 内的函数。例如,调用 Windows 的消息框函数:
function MessageBoxA(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
function MessageBoxA external 'user32.dll' name 'MessageBoxA';
动态加载与函数解析(延迟绑定)
当需要在运行时决定加载哪个 DLL 或函数时,可使用以下三个核心 API:
LoadLibrary:加载指定 DLL 并返回句柄GetProcAddress:根据函数名获取其地址FreeLibrary:释放已加载的 DLL 资源
首先定义与目标函数匹配的过程类型:
type
TMsgBox = function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
var
MsgProc: TMsgBox;
LibHandle: HMODULE;
执行动态加载和调用:
LibHandle := LoadLibrary('user32.dll');
if LibHandle <> 0 then
begin
MsgProc := GetProcAddress(LibHandle, 'MessageBoxW');
if Assigned(MsgProc) then
MsgProc(0, 'Hello', 'Info', MB_OK);
FreeLibrary(LibHandle);
end;
创建可被外部调用的 DLL 模块
使用 Delphi 的 DLL 工程模板创建一个共享库,包含一个公开过程:
library MySharedLib;
uses
SysUtils, Classes, Dialogs;
{$R *.res}
procedure ShowMessageFromDLL;
begin
ShowMessage('DLL 已成功加载并执行!');
end;
exports
ShowMessageFromDLL;
begin
end.
在主程序中通过外部引用调用该函数:
procedure ShowMessageFromDLL; external 'MySharedLib.dll';
procedure TForm1.ButtonClick(Sender: TObject);
begin
ShowMessageFromDLL;
end;
将资源文件嵌入 DLL 并提取使用
将图像等资源以 .rc 文件形式编译进 DLL,便于封装。
- 新建 DLL 项目,保存为默认名称。
- 创建资源脚本文件
Resource.rc,内容如下:IMG_ICON BITMAP "C:\temp\logo.bmp" - 将此 .rc 文件添加至 DLL 项目,IDE 自动插入编译指令:
{$R 'Resource.res' 'Resource.rc'} - 编译生成
MySharedLib.dll,复制到C:\temp目录。
在应用程序中读取并显示嵌入的图像:
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
private
procedure DrawEmbeddedImage;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormPaint(Sender: TObject);
begin
DrawEmbeddedImage;
end;
procedure TForm1.DrawEmbeddedImage;
var
LibHandle: HMODULE;
Bitmap: TBitmap;
begin
LibHandle := LoadLibrary('C:\temp\MySharedLib.dll');
if LibHandle = 0 then Exit;
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromResourceName(LibHandle, 'IMG_ICON');
Canvas.Draw(20, 20, Bitmap);
finally
FreeLibrary(LibHandle);
Bitmap.Free;
end;
end;
end.
运行后窗体将显示嵌入在 DLL 中的图片。