`
v5qqcom
  • 浏览: 1281755 次
文章分类
社区版块
存档分类
最新评论

Delphi中动态链接库两种调用方式的比较

 
阅读更多

一、动态链接库的概念

动态链接库(Dynamic Link Library,缩写为DLL)是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。动态链接库文件的扩展名一般是dll,也有可能是drv、sys和fon,它和可执行文件(exe)非常类似,区别在于DLL中虽然包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。

动态链接是相对于静态链接而言的。所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。

一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射文件实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间,如果一个DLL被多个进程调用,每个进程都会收到该DLL的一份映像。与16位Windows不同,在Win32中 DLL可以看作是每个进程自己的代码。

二、动态链接库的优点

1. 共享代码、资源和数据

使用DLL的主要目的就是为了共享代码,DLL的代码可以被所有的Windows应用程序共享。

2. 隐藏实现的细节

DLL中的例程可以被应用程序访问,而应用程序并不知道这些例程的细节。

3. 拓展开发工具如Delphi的功能

由于DLL是与语言无关的,因此可以创建一个DLL,被C++、VB或任何支持动态链接库的语言调用。这样如果一种语言存在不足,就可以通过访问另一种语言创建的DLL来弥补。

三、动态链接库的实现方法

1. Load-time Dynamic Linking

这种用法的前提是在编译之前已经明确知道要调用DLL中的哪几个函数,编译时在目标文件中只保留必要的链接信息,而不含DLL函数的代码;当程序执行时,利用链接信息加载DLL函数代码并在内存中将其链接入调用程序的执行空间中,其主要目的是便于代码共享。

2. Run-time Dynamic Linking

这种方式是指在编译之前并不知道将会调用哪些DLL函数,完全是在运行过程中根据需要决定应调用哪个函数,并用LoadLibrary和GetProcAddress动态获得DLL函数的入口地址。

四、DLL的两种调用方式在Delphi中的比较

编写DLL的目的是为了输出例程供其他程序调用,因此在DLL的工程文件中要把输出的例程用 Exports关键字引出。在调用DLL的应用程序中,需要声明用到的DLL中的方法,声明格式要和DLL中的声明一样。访问DLL中的例程有静态调用和动态调用两种方式。静态调用方式就是在单元的Interface部分用External指示字列出要从DLL中引入的例程;动态调用方式就是通过调用 Windows的API包括LoadLibrary函数、GetProcAddress函数以及FreeLibrary函数动态的引入DLL中的例程。

静态调用方式所需的代码较动态调用方式所需的少,但存在着一些不足,一是如果要加载的DLL 不存在或者DLL中没有要引入的例程,这时候程序就自动终止运行;二是DLL一旦加载就一直驻留在应用程序的地址空间,即使DLL已不再需要了。动态调用方式就可解决以上问题,它在需要用到DLL的时候才通过LoadLibrary函数引入,用完后通过FreeLibrary函数从内存中卸载,而且通过调 GetProcAddress函数可以指定不同的例程。最重要的是,如果指定的DLL出错,至多是API调用失败,不会导致程序终止。以下将通过具体的实例说明说明这调用方式的使用方法。

1. 静态调用方式

示例程序创建了一个DLL,其中仅包含一个求两个整数的和的函数,在主程序中输入两个整数,通过调用该DLL,即可求出两个整数的和。

该DLL的程序代码如下:

library AddNum;
uses
SysUtils,
Classes;
{$R *.res}
function AddNumber(Num1,Num2:integer):integer;stdcall; //定义求和函数
 begin
  result:=Num1+Num2;
 end;
  exports
  AddNumber; //引出求和函数
 begin
end.

主程序在调用该DLL时,首先在interface部分声明要调用的函数:

function AddNum(Num1,Num2:integer):integer;stdcall;external 'AddNum.dll'
name 'AddNumber';

然后在按钮控件的事件中写入如下代码:

procedure TForm1.Button1Click(Sender: TObject);
var
 Number1,Number2:integer;
 Sum:integer;
begin
 Number1:=strtoint(Edit1.Text);
 Number2:=strtoint(Edit2.Text);
 Sum:=AddNum(Number1,Number2); //调用求和函数计算结果
 Edit3.Text:=inttostr(Sum);
end;

2.动态调用方式

这个示例程序创建了一个显示日期的DLL,其中包含一个窗体。

程序中定义了一个ShowCalendar函数,返回在这个窗体中设定的日期。函数定义如下:

function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;
var
 DLLForm: TDLLForm;
begin
 Application.Handle := AHandle;
 DLLForm := TDLLForm.Create(Application); //创建并显示窗体
 try
  DLLForm.Caption := ACaption;
  DLLForm.ShowModal; //显示方式为模式化
  Result := DLLForm.calDLLCalendar.CalendarDate; //返回设定日期
 finally
  DLLForm.Free; //用完后卸载该窗体
 end;
end;

在DLL的工程文件中用exports ShowCalendar; 语句引出该函数。下面通过一个简单的应用程序测试一下该DLL文件。新建一个工程文件,在窗体中放置一个Label控件和一个按钮控件,在按钮控件的 OnClick事件中编写如下代码:

procedure TMainForm.Button1Click(Sender: TObject);
var
 OneHandle : THandle; //定义一个句柄变量
begin
 OneHandle := LoadLibrary('Clendar.dll'); //动态载入DLL,并返回其句柄
 try
  if OneHandle <> 0 then //如果载入成功则获取ShowCalendar函数的地址
   @ShowCalendar := GetProcAddress(OneHandle, 'ShowCalendar');
   if not (@ShowCalendar = nil) then
    //如果找到该函数则在主窗体的Label1中显示DLL窗体中设定的日期
    Label1.Caption := DateToStr(ShowCalendar(Application.Handle, Caption))
   else
    RaiseLastWin32Error;
 finally
  FreeLibrary(OneHandle); //调用完毕收回DLL占用的资源
 end;
end;

从以上程序中可以看到DLL的动态调用方式比静态调用方式的优越之处。DLL例程在用到时才被调入,用完后就被卸载,大大减少了系统资源的占用。在调用LoadLibrary函数时可以明确指定DLL的完整路径,如果没有指定路径,运行时首先查找应用程序载入的目录,然后是Windows系统的System目录和环境变量Path设定的路径。

五、结束语

由于动态链接库可以实现代码和资源的共享,大大减少系统资源的占用,因此在当今的应用程序开发中起着非常重要的作用。Delphi是现今流行的应用软件开发工具,本文就如何在Delphi中使用动态链接库给出了一定程度上的阐述。

分享到:
评论

相关推荐

    Delphi中动态链接库两种调用方

    Delphi中动态链接库两种调用方,很有用的

    DLL动态链接库的实现及调用(VC++,Delphi)

    动态链接库(DLL)的编译实例,包括_cdecl和stdcall两种常见函数调用约定的实现,并且解决了名字修改问题,在实例代码中有详细的说明!2.针对不同的函数调用约定,以及动态调用DLL库和静态调用DLL库分别提供了调用实例...

    DLL编程(阿蒙工作室).rar

    DLL编程 ☆ DLL编程相关资料1 ☆ DLL编程相关资料2 ☆ 用VC编DLL的方法 ☆ 纯资源DLL的编写 ...☆ Delphi中动态链接库两种调用方式比较 ☆ DLL的调试 ☆ DLL综合资料二 ☆ DLL综合资料一 ☆ dynamic_dll_loading

    Delphi5开发人员指南

    第9章 动态链接库 234 9.1 究竟什么是DLL 234 9.2 静态链接与动态链接 235 9.3 为什么要使用DLL 236 9.3.1 共享代码、资源和数据 236 9.3.2 隐藏实现的细节 237 9.3.3 自定义控件 237 9.4 创建和使用DLL 237 9.4.1 ...

    Delphi开发范例宝典目录

    实例244 两种信息发送方式 310 实例245 使用线程添加数据 312 实例246 功能快捷键 314 第7章 注册表 317 7.1 操作注册表 318 实例247 怎样存取注册表信息 318 实例248 注册表保存注册信息 319 实例...

    CV全自动图形图片验证码识别软件

    可供多种可调用动态链接库的编程语言调用(vc、vb、delphi、 java、c#、vb.net、asp、模拟精 灵等),调用简单、灵活,可以通过传递文件名或图片数据流两种方式进行识别,提供函数调用说明及各种语言的调用具体实例。...

    易语言程序免安装版下载

     静态编译后的易语言可执行程序(exe)和动态链接库(dll),运行时不再依赖任何支持库文件,文件尺寸更小(相对以前的独立编译),PE结构更合理(取消了“易格式体”),加载速度更快,而且有效解决了“病毒误报”和...

    自己写的dll的简介

    为何DLL 先看看静态库与DLL的不同之处 可执行文件的生成(Link期):前者很慢(因为要将库中的所有符号定义Link到EXE文件中),而后者很快(因为后者被Link的引入库文件无符号...Windows API编程之动态链接库(DLL)

    彩虹UDA软件狗工具带硬复制工具

    在原有加密方式基础上,新增 C 语言高强度动态库加密方式,并有效运用动态库认证安全机制,确保动态库调用具有无与伦比的安全可靠性。 支持 ActiveX 控件 开发商可以在网页中或 VB 、 VC 中使用 ActiveX 控件对...

    Http/FTP多线程断点续传下载组件

    点量Http、FTP下载内核源码使用高效的c++代码编写,提供标准的动态链接库(DLL),可供C/C++、Delphi、C#、Java、VB等语言和各常用开发环境调用,让您完全像调用系统API一样的调用。 点量Http/FTP组件的功能简介...

    vc++ 应用源码包_1

    动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写操作类实例 VC++版源代码统计工具 内含自绘...

    vc++ 应用源码包_2

    动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写操作类实例 VC++版源代码统计工具 内含自绘...

    vc++ 应用源码包_6

    动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写操作类实例 VC++版源代码统计工具 内含自绘...

    vc++ 应用源码包_5

    动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写操作类实例 VC++版源代码统计工具 内含自绘...

    vc++ 应用源码包_3

    动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕绘图操作,实现电子标尺数据计算以及显示,有数据库操作保存数据。 VC++ ini文件读写操作类实例 VC++版源代码统计工具 内含自绘...

    vc++ 开发实例源码包

    详细讲解了Crypt++的加密解密的使用以及其它的加密解密方法(例如base64加解密、哈希加解密以及其它的文件加解密),分静态库和动态库方法。 JSCalls_demo js调用的演示源码 树控件拖动 演示了在树控件中来回拖动...

    PE资源修复

    本引擎以动态链接库(dll)形式实现,该 dll 共输出五个函数,函数按功能分为两大类。 第一类:PE 文件资源修复功能。修复后,引擎会无条件地为 PE 文件增加一个资源节,会导致文 件体积变大,该功能适合进行简单...

    短信猫:又称GSM MODEM,GSM猫,无线猫,短信模块,GSM模块

    基于多年的开发经验,为客户提供一套基于动态链接库(DLL)技术的短信猫开发包,可以支持所有的 WINDOWS 环境下开发工具,也提供支持 JAVA 开发的 JAR 包。 短信猫通信中间件:这是我们独家提供的基于数据库接口的...

    C#微软培训资料

    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...

Global site tag (gtag.js) - Google Analytics