请教各位高手,本人对DLL文件不是很熟悉,请指教DLL具体有何作用,它与程序的接口是如何的?
解决方案 »
- 请高手来看下TServerSocket的问题
- Filter的过滤条件有问题,不能and和or一起用?
- fastreport里面的MasterData1怎么显示边框啊??
- 0XFFFF、0X0020这些是不是十六进制数?如何转为byte类型
- 怎么安装RxLib275d7和toolbar2000?高手救我:)
- StringGrid怎么只能在最后一行添加行,而可以删除任意行?
- 如何讓Tmemo總是顯示第一行,我用add加入很多行,完成后focus總在最后一行,我想讓他回到第一行.請幫忙
- 如何在数据库中查询unicode字符串?
- 我的电脑中Delphi60和BCB60不能和平共处了!
- VB程序员转Delphi应该注意什么(请指教)
- dbgrid显示问题简单问题,急在线等待50分
- lxl(是我,不是风) 和 angle097113(抵制日货,人人有责!) 请进!!!
function Add(val1,val2:integer):integer;stdcall;
function Substract(val1,val2:integer):integer;stdcall;
implementation
……---- 2)在DLL创建类
---- *添加一个新单元UseClass.pas ---- * 定义一个基类 TDllCalc=class
public
function Multiply(val1,val2:integer):integer;virtual;abstract;
function Divide(val1,val2:integer):integer;virtual;abstract;
end;---- * 定义一派生类并实现其函数
TDllCalcImpl=class(TDllCalc)
public
function Multiply(val1,val2:integer):integer;override;
function Divide(val1,val2:integer):integer;override;
end;
implementation
……
---- * 声明一个实现函数
function ClassCalcImpl:TDllCalc;stdcall;
function ClassCalcImpl:TDllCalc;
begin
result:=TDllCalcImpl.Create;
end;---- 3)在项目dllDemo.dpr单元中添加exports子句,并在其中声明输出函数
exports
Add,Substract,ClassCalcImpl;---- 4)编译生成一个.dll文件(dllDemo.dll)
---- 3、在Delphi中使用DLL ---- 建立一个应用程序这prj1.dpr,与DLL在同一目录下。在form中有5个button,2个spinedit,2个bevel,7个label。 ---- 在Delphi中调用DLL有两种方式:隐式调用和显式调用。 ---- 1)隐式调用 ---- ①直接对函数的调用 ---- 在单元implementation部分声明两个函数,必须声明为stdcall,同时加上external dllName
function Add(val1,val2:integer):integer
;stdcall;external 'dllDemo.dll';
function Substract(val1,val2:integer)
:integer;stdcall;external 'dllDemo.dll'; ---- 两个button的click事件为:
procedure TfrmDemo1.GetVal(var val1, val2: integer);
begin
val1:=sedt1.Value;
val2:=sedt2.Value;
end; procedure TfrmDemo1.btnAddClick(Sender: TObject);
begin
GetVal(FVal1,FVal2);
label1.Caption:=inttostr(add(FVal1,FVal2));
end; procedure TfrmDemo1.btnSubstractClick(Sender: TObject);
begin
GetVal(FVal1,FVal2);
label2.Caption:=inttostr(Substract(FVal1,FVal2));
end; ---- ②对类的引用
---- * 在引用单元中声明一个基类; TDllCalc=class
public
function Multiply(val1,val2:integer):integer;virtual;abstract;
function Divide(val1,val2:integer):integer;virtual;abstract;
end;
function ClassCalcImpl:TDllCalc;stdcall;external 'dllDemo.dll';---- * 然后定义一个对象。
private
{ Private declarations }
FVal1,FVal2:integer;
NewObject:TDLLCalc;
procedure GetVal(var val1,val2:integer);
Implementation
procedure TfrmDemo1.FormCreate(Sender: TObject);
begin
NewObject:=ClassCalcImpl;
end; procedure TfrmDemo1.btnMultiplyClick(Sender: TObject);
begin
GetVal(FVal1,FVal2);
label3.Caption:=inttostr(NewObject.Multiply(FVal1,FVal2));
end; procedure TfrmDemo1.btnDivideClick(Sender: TObject);
begin
GetVal(FVal1,FVal2);
label4.Caption:=inttostr(NewObject.Divide(FVal1,FVal2));
end; procedure TfrmDemo1.FormDestroy(Sender: TObject);
begin
NewObject.Free;
end;
---- 2)显式调用
---- 虽然隐式调用DLL比较方便,但这并不是最好的方式。假若一个DLL包含许多例程,其中大部分例程可能根本用不着,因此把整个DLL都调入内存显然是浪费,尤其是当一个应用程序需要用到多个动态链接库。另一种情况是,假设有一组标准的函数有多个版本,分别由多个DLL实现。在这种情况下,最好在需要哪个版本的时候就调入哪个DLL,这就是指显式调用DLL。 ---- 定义一个函数类型 TAdd=function(val1,val2:integer):integer;stdcall; const
DllName='DllDemo.dll'; procedure TfrmDemo1.bntDynaCallClick(Sender: TObject);
var
HInst:THandle;
FPointer:TFarProc;
MyFunc:TAdd;
begin
HInst:=LoadLibrary(DllName); //调用DLL
if HInst>0 then //如果成功
try
FPointer:=GetProcAddress(HInst,PChar('Add')); //获得函数地址
if FPointer< >nil then
begin
GetVal(FVal1,FVal2);
MyFunc:=TAdd(FPointer);
label5.caption:=inttostr(MyFunc(FVal1,FVal2));
end
else
messagebox(0,'Funtion Add not found','Warning',MB_OK);
finally
FreeLibrary(HInst);
end
else
messagebox(0,'DllName not found','Warning',MB_OK);
end;