DLL笔记
下面以DLL简单程序的测试,来展示DLL的用法和各种注意点:
一个DLL程序:
library Project2;
uses
SysUtils,Classes;
{$R *.res}
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.
l 一个调用程序:
unit DLLTest;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
DLL='project2.DLL';
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function Min(X, Y: Integer): Integer; stdcall; external DLL;
function Max(X,Y:Integer):Integer; stdcall; external DLL;
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=IntToStr(Min(3,5));
end;
end.
输出结果当然是3。
l 另一个调用程序:
unit DLLTest;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
DLL='project2.DLL';
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function Min(X, Y: Integer): Integer; stdcall; external DLL;
function Max(X, Y: Integer): Integer; stdcall; external DLL;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=IntToStr(Min(3,5));
end;
end.
输出结果也是3。
结论:无论在Interface还是implementation部分声明,都可以,但区别当然也是很明显的,声明在Interface的可以被其他单元调用,而声明在implementation的,只能在自己的单元中被调用。要可以被其他单元调用,还有别一种形式,代码如下:
unit DLLTest;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
DLL='project2.DLL';
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function Min(X, Y: Integer): Integer; stdcall;
function Max(X, Y: Integer): Integer; stdcall;
var
Form1: TForm1;
implementation
{$R *.dfm}
function Min; external DLL;
function Max; external DLL;
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=IntToStr(Min(3,5));
end;
end.
l 将其中一个函数的大小写变一下:
function min(X, Y: Integer): Integer; stdcall; external DLL;
程序出现错误,说明对于DLL的函数声明是大小写敏感的。
l 现在将DLL文件的Exports块修改如下:
exports
Min name ‘Max’,
Max name ‘Min’;
再将上面调用程序运行一遍,输出结果是5,说明,如上声明之后,在DLL程序中的Min函数,它输出为Max了,而Max则输输出为Min了。
l 再将Exports块改为如下形式:
exports
Min name index 1,
Max name index 2;
再将调用程序的的声明变为如下:
function Min; external DLL index 2;
//function Max; external DLL;
运行结果为5,则说明当DLL程序声明Index后,外部程序调用时如果也用Index,则调用DLL哪个函数由Index来决定。如果DLL没有在函数输出后面加Index,则外部程序加上Index无效。
l 将调用程序的函数声明变为如下:
function Min; external DLL name 'Max';
function Max; external DLL name 'Min';
则程序运行结果是5,说明如果用了name,则外部函数实际对应的是DLL中和Name后面的字符串相同的函数,大小敏感。
{三}C基本类型与Delphi类型的对应
//整型
INT64 = Int64 有符号64位整数
INT = Integer 有符号32位整数
LONG = Longint 有符号32位整数
WPARAM = Longint 有符号32位整数
LPARAM = Longint 有符号32位整数
LRESULT = Longint 有符号32位整数
HANDLE = Loingint 有符号32位整数
UINT = LongWord 无符号32位整数
DWORD = DWORD 无符号32位整数
SHORT = Smallint 有符号16位整数
WORD = Word 无符号16位整数
BYTE = Byte 无符号8位整数
//浮点型
FLOAT = Single 占4个字节
DOUBLE = Double 占8个字节
//字符型
CHAR = Char
WCHAR = WideChar;
PWChar = PWideChar;
LPSTR = PAnsiChar;
LPCSTR = PAnsiChar;
LPCTSTR = PAnsiChar;
LPTSTR = PAnsiChar;
LPWSTR = PWideChar;
LPCWSTR = PWideChar;
//布尔型
BOOL = LongBool; 4个字节
bool = Boolean; 1个字节