调用DLL有两种方法,一种是在应用程序装载时调用,另一种是在应用程序运行时调用。
(1) 装载时调用DLL
在调用DLL的Pas文件中,对DLL函数进行外部声明,声明应位于Implementation后,形式如下:
Implementation |
例如,Function AdvDVP_GetNoOfDevices(pNoOfDevs: PINT):Integer ; stdcall;External 'xxx.dll';xxx为待测的dll名称。
这里有两个问题:第一,参考书上的指针数据类型,type 指针类型名称=:^ type,如
pNoOfDevs: ^Integer是通不过的,必须改为pNoOfDevs: PINT。
第二,如果是通过新建了一个unit来专门声明待测试的所有函数,变量等,则不能只在Implementation声明,否则,编译出现未声明的identifier的error。
要有两部分:
interface uses windows;
Function AdvDVP_InitSDK():Integer ; stdcall;
implementation
function AdvDVP_InitSDK; External 'xxx.dll';//xxx为待测试的dll名称
其中External关键字后面的引号内是DLL的文件名,该文件一般应放在系统的system目录下,或与调用它的项目同一目录。声明以后即可在Pas文件任何地方引用DLL函数。
否则,如果在工程下,直接声明,那么只要implementation下添加下面代码就可以了:
Function AdvDVP_InitSDK():Integer ; stdcall; external 'DVP7010B.dll';
在form中,添加button,并直接调用函数就可以了。
ret := AdvDVP_InitSDK();
装载时调用DLL的优点是速度较快,程序间也可共享代码。
(2) 运行时调用DLL
DLL的另一种调用方法是在运行时调用。这种方法要调用到Windows的API函数LoadLibrary,GetProcAddress,FreeLibrary等。此方法主要用于调用其它语言,特别是C++编译的DLL。
首先在欲调用DLL的程序Type类型声明处加入一句:
type
TAdvDVP_InitSDK=Function:Integer; stdcall;
此句的作用如同C++中声明的函数指针。
然后定义如下变量∶
var
AdvDVP_InitSDK:TAdvDVP_InitSDK;
Handle:THandle;
在调用DLL处加入如下语句进行DLL装载:
begin
Handle:=LoadLibrary('xxx.dll'); //xxx为待测试的dll名称
if Handle<>0 then
begin
@AdvDVP_InitSDK:=GetProcAddress(Handle,'AdvDVP_InitSDK');
end
else
Application.MessageBox('加载dll出错 ', mb_OK);
end;
下面可直接调用DLL了:
var
ret: Integer;
I :Integer;
res:Integer;
begin
ret := AdvDVP_InitSDK();
if ret=1 Then
begin
Application.MessageBox('Initing SDK succeeded.', 'Look', mb_OK);
end;
MessageValue.Text := IntToStr(ret);
end;
调用完以后,用FreeLibrary释放DLL占用的内存:
FreeLibrary(Handle); |