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

Posted 函数

篇首语:书到用时方恨少,事非经过不知难。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Delphi中动态链接库两种调用方式的比较相关的知识,希望对你有一定的参考价值。

Delphi中动态链接库两种调用方式的比较  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

一 动态链接库的概念

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

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

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

二 动态链接库的优点

. 共享代码 资源和数据

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

. 隐藏实现的细节

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

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

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

三 动态链接库的实现方法

. Load time Dynamic Linking

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

. 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调用失败 不会导致程序终止 以下将通过具体的实例说明说明这调用方式的使用方法

. 静态调用方式

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

该DLL的程序代码如下

library AddNum;  uses  SysUtils   Classes;

$R * res

function AddNumber(Num Num :integer):integer;stdcall; file://定义求和函数  begin  result:=Num +Num ;  end;  exports  AddNumber; file://引出求和函数  begin  end      主程序在调用该DLL时 首先在interface部分声明要调用的函数

function AddNum(Num Num :integer):integer;stdcall;external AddNum dll   name AddNumber ;   然后在按钮控件的事件中写入如下代码

procedure TForm Button Click(Sender: TObject);  var  Number Number :integer;   Sum:integer;  begin  Number :=strtoint(Edit Text);  Number :=strtoint(Edit Text);  Sum:=AddNum(Number Number ); file://调用求和函数计算结果  Edit Text:=inttostr(Sum);  end;    .动态调用方式

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

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

function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;  var  DLLForm: TDLLForm;  begin  Application Handle := AHandle;  DLLForm := TDLLForm Create(Application); file://创建并显示窗体  try  DLLForm Caption := ACaption;  DLLForm ShowModal; file://显示方式为模式化  Result := DLLForm calDLLCalendar CalendarDate; file://返回设定日期  finally  DLLForm Free; file://用完后卸载该窗体  end;  end;   在DLL的工程文件中用exports ShowCalendar; 语句引出该函数 下面通过一个简单的应用程序测试一下该DLL文件 新建一个工程文件 在窗体中放置一个Label控件和一个按钮控件 在按钮控件的OnClick事件中编写如下代码

procedure TMainForm Button Click(Sender: TObject);  var  OneHandle : THandle; file://定义一个句柄变量  begin  OneHandle := LoadLibrary( Clendar dll ); file://动态载入DLL 并返回其句柄  try  if OneHandle <> then file://如果载入成功则获取ShowCalendar函数的地址  @ShowCalendar := GetProcAddress(OneHandle ShowCalendar );  if not (@ShowCalendar = nil) then  file://如果找到该函数则在主窗体的Label 中显示DLL窗体中设定的日期  Label Caption := DateToStr(ShowCalendar(Application Handle Caption))  else  RaiseLastWin Error;  finally  FreeLibrary(OneHandle); file://调用完毕收回DLL占用的资源  end;  end;   从以上程序中可以看到DLL的动态调用方式比静态调用方式的优越之处 DLL例程在用到时才被调入 用完后就被卸载 大大减少了系统资源的占用 在调用LoadLibrary函数时可以明确指定DLL的完整路径 如果没有指定路径 运行时首先查找应用程序载入的目录 然后是Windows系统的System目录和环境变量Path设定的路径

五 结束语

cha138/Article/program/Delphi/201311/8480

相关参考

知识大全 Delphi 中动态链接库(dll)的建立和使用[1]

Delphi中动态链接库(dll)的建立和使用[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 动态链接库编程(一)[4]

DELPHI基础教程:动态链接库编程(一)[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(一)[3]

DELPHI基础教程:动态链接库编程(一)[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(一)[2]

DELPHI基础教程:动态链接库编程(一)[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(一)[1]

DELPHI基础教程:动态链接库编程(一)[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(二)[3]

DELPHI基础教程:动态链接库编程(二)[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(二)[4]

DELPHI基础教程:动态链接库编程(二)[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(二)[2]

DELPHI基础教程:动态链接库编程(二)[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 动态链接库编程(二)[1]

DELPHI基础教程:动态链接库编程(二)[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 为文章标题链接添加动态载入效果

    很多朋友应该都会发现在我的博客里移动和点击标题都有一些动态效果右移的效果请移步上次写的文章《分享本站标题链接平滑右移效果》今天写的是点击之后的那个动态loading的效果两种的效果到主页点击标