动态载入DLL

unit MainForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TDLLDemo = function(x, y: Integer): Integer; stdcall;
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
DllHandle: THandle;
DllPointer: Pointer;
MyDLLFunc: TDLLDemo;
implementation


{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
DllHandle := LoadLibrary('DLLDemo.dll');
if DllHandle > 0 then
try
DllPointer := GetProcAddress(DllHandle, PChar('AddIt'));
if DllPointer <> nil then begin
MyDLLFunc := TDLLDemo(DllPointer);
Edit1.Text := IntToStr(MyDLLFunc(5, 3));
end
else
ShowMessage('没有找到AddIt');
DllPointer := GetProcAddress(DllHandle, PChar('SubIt'));
if DllPointer <> nil then begin
MyDLLFunc := TDLLDemo(DllPointer); //此处还可用如下形式
//1. @MyDLLFunc := GetProcAddress(DllHandle, PChar('SubIt'));
//2. @MyDLLFunc := DllPointer;
// 家@操作符的目的是--前加上取址运算符@,这样就不会在编译时出现类型转换错误。
Edit2.Text := IntToStr(MyDLLFunc(5, 3));
end
else
ShowMessage('没有找到SubIts');
finally
FreeLibrary(DllHandle);
end
else
ShowMessage('没有找到DLLDemo.dll');
end;

end.

{

三个Win32 API函数:LoadLibrary()、FreeLibrary()、GetProcAddress()。
LoadLibrary()声明如下:

function LoadLibrary(lpLibFileName: Pchar): HMODULE; stdcall;

上述函数调入由 lpLibFileName 参数指定的 DLL 模块,并将其映射到调用进程的地址空间。如果调
用成功,函数将返回该模块的句柄;若失败,返回值为0,并触发一异常。你可以查阅在线帮助中
LoadLibrary()函数的详细说明以及可能返回的错误值。

FreeLibrary()声明如下:

function FreeLibrary(hLibModule: HMODULE): BOOLEAN; stdcall;

FreeLibrary()函数减小 hLibModule 指定的库的实例计数。当该 DLL 的实例计数是零时,调用的 DLL
就会被释放。实例计数记录使用这个 DLL 的任务数。
GetProcAddress()是这样定义的:

function GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
GetProcAddress() 返回的是一个函数在模块中的地址,其中由 hModule 参数指定模块。hModule 是
从 LoadLibrary() 函数返回的结果THandle。如果 GetProcAddress() 调用失败,则返回 nil。你只有调
用 GetLastError() 才能获得详细的错误信息。

}

原文地址:https://www.cnblogs.com/spiritofcloud/p/3978305.html