The structure of a DLL is identical to that of a program, except that a DLL begins with the reserved word library (instead of program).
The following example shows a DLL with two exported functions, Min and Max.
library MinMax;
function Min(X, Y: Integer): Integer; stdcall;
begin
if X < Y then Min := X else Min := Y;
end;
function Max(X, Y: Integer): Integer; stdcall;
begin
if X > Y then Max := X else Max := Y;
end;
exports
Min,
Max;
begin
end.
If you want your DLL to be available to applications written in other languages, it抯 safest to specify
stdcall in the declarations of exported functions. Other languages may not support Object Pascal抯 default register calling convention.
DLLs can be built from multiple units. In this case, the library source file is frequently reduced to a
uses clause, an exports clause, and the DLL抯 initialization code. For example,
InitEditors,
DoneEditors index 17 name Done,
InsertText name Insert,
DeleteSelection name Delete,
FormatSelection,
PrintSelection name Print,
...
SetErrorHandler;
begin
InitLibrary;
end.
You can put exports clauses in the interface or implementation section of a unit. Any library that includes such a unit in its uses clause automatically exports the routines listed the unit抯 exports clauses梬ithout the need for an exports clause of its own.
Only routines that a library explicitly exports are available for importing by other libraries or programs.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
You can access routines in a DLL through direct calls to Windows library functions, including LoadLibrary, FreeLibrary, and GetProcAddress (all declared in Delphi抯 Windows unit). In this case, use procedural-type variables to reference the imported routines. For example,
uses Windows, ...;
type
TTimeRec = record
Second: Integer;
Minute: Integer;
Hour: Integer;
end;
TGetTime = procedure(var Time: TTimeRec);
THandle = Integer;
var
Time: TTimeRec;
Handle: THandle;
GetTime: TGetTime;
...
begin
Handle := LoadLibrary('DATETIME.DLL');
if Handle <> 0 then
begin
@GetTime := GetProcAddress(Handle, 'GetTime');
if @GetTime <> nil then
begin
GetTime(Time);
with Time do
WriteLn('The time is ', Hour, ':', Minute, ':', Second);
end;
FreeLibrary(Handle);
end;
end;
When you import routines this way, the DLL is not loaded until the code containing the call to LoadLibrary executes. The DLL is later unloaded by the call to FreeLibrary. This allows you to conserve memory, and to run your program even when some of the DLLs it uses are not present.
DLL中的接口
function DLLInterfaceName(AStr:string):boolean;stdcall;
这是调用时的代码:
type
TDLLInterfaceName=function (AStr:string):Boolean;stdcall;
function DLLInterfaceName(AStr:string):Boolean;stdcall;
var
DLLName:string;
h:Thandle;
m:TDLLInterfaceName
begin
result:=false;
DLLName:='a.dll';
h:=LoadLibrary(pchar(DLLName)));
try
if h=0 then
begin
Messagebox(0,pchar('动态库调用失败!'),pchar('提示'),MB_OK+MB_ICONINFORMATION+MB_TASKMODAL);
exit;
end;
@m:=GetProcAddress(h,'DLLInterfaceName');
if @m=nil then
begin
Messagebox(0,pchar('动态库调用接口错误!'),pchar('提示'),MB_OK+MB_ICONINFORMATION+MB_TASKMODAL);
exit;
end;
m('str');
result:=true;
finally
Freelibrary(h);
end;
end;