DELPHI (6).ppt_第1页
DELPHI (6).ppt_第2页
DELPHI (6).ppt_第3页
DELPHI (6).ppt_第4页
DELPHI (6).ppt_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1,第六章,Dll编程技术,本章要点: Dll概述 Dll的Delphi实现 Dll的调用,2,6.1 Dll概述,动态链接库是程序模块,它包括代码、数据或资源,能够被 其他的Windows应用程序共享。DLL的主要特点之一是应用 程序可以在运行时调入代码执行,而不是在编译时链接代码, 因此,多个应用程序可以共享同一个D L L的代码。事实上, 文件K e r n e l 3 2 . d l l、U s e r 3 2 . d l l、G D I 3 2 . d l l就 是核心Wi n 3 2系统的动态链接库。K e r n e l . d l l负责内存、 进程和线程的管理。U S E R

2、 3 2 . D L L包含了一些程序,是 创建窗口和处理Wi n 3 2消息的用户接口。G D I 3 2 . D L L 负责处理图形。 使用动态链接库的另一个特点是有利于应用程序的模块化, 一个DLL基本上类似于一个Windows可执行文件( * .EXE )。 一个主要的区别是, D L L不是一个独立的可执行文件,尽管 它可能包含了可执行代码。大部分D L L文件的扩展名是.dll。,3,DLL通过动态链接技术(dynamic linking)与其他应用程序共享代码,当一个应用程序使用了一个DLL,Win32系统会确保内存中只有一个该DLL的拷贝,这是通过内存映射文件来实现的。DLL

3、首先被调入Win32的全局堆,然后映射到调用这个DLL进程的地址空间。在Win32系统中,每个进程都被分配有自己的32位线性地址空间。当一个DLL被多个进程调用时,每个进程都会获得该DLL的一份映像。,有关D L L的一些术语如下: 应用程序,一个扩展名为.exe的Windows程序。 可执行文件,一个包含可执行代码的文件,它包括.dll文件和. e x e文件。,为什么要使用DLL?,共享代码、资源和数据 隐藏实现的细节,4, 实例,当提到应用程序和D L L时,在内存中出现的可执行文件就是实例。Wi n 3 2系统通过实例句柄的方式来引用实例。例如,如果一个应用程序运行两次,就会有应用程序

4、的两个实例,同时就有两个实例句柄。当一个D L L被调入时,实例及其相应的实例句柄同时产生。应该注意的是,这里所提的实例与类的实例不能混淆。 模块,在3 2位Wi n d o w s系统中,模块和实例可以说是同义的。而在1 6位的Wi n d o w s系统中,是建立一个模块数据库来管理模块的,一个模块对应一个模块句柄。在Wi n 3 2中,应用程序的每一个实例都拥有自己的地址空间;所以,没有必要为模块单独指定标识符。不过,微软仍然保留了它自己的术语。注意一点,模块和实例是同一个概念。 任务,Wi n d o w s是一个多任务(或任务切换)环境,所以它必须能够为运行的多个实例合理分配系统资源

5、和时间。于是,Wi n d o w s建立一个任务数据库,这个数据库包括任务的实例句柄和其他必要信息,以此实现任务切换功能。任务是Wi n d o w s用来管理和分配资源与时间段的重要元素。,5,6.2 静态链接与动态链接,静态链接,指D e l p h i编译器把要调用的函数和过程编译成可执行代码。函数的代码可存留在应用程序的. d p r文件或一单元中。当链接用户的应用程序时,这些函数与过程便成为最终的可执行文件的一部分。也就是说,函数和过程都在程序的. e x e文件中。 程序运行时,函数和过程随程序一起调入内存,它们的位置与程序的位置是相关的。当主程序需要调用函数或过程时,流程将跳转

6、到函数或过程所在的位置,执行完函数或过程的代码,将返回主程序调用位置。而函数或过程的相对位置,在链接时就已经确定了。,动态链接,在程序运行时,通过引用一个外部函数(该函数包含在DLL中)而将该函数链接到可执行文件中。其中的引用可以在应用程序中声明,但是通常情况下是放在一个专门的引入( import )单元里,在这个单元里可以声明引入的函数、过程以及DLL所需的多种类型的定义。,6,6.3创建和使用DLL,6.3.1 创建静态连接的Dll(一),一、使用公共单元定义接口 使用编译指令:DEFINE 如果把上面的D L L共享出去,就必须用户提供test6-1.dll和unitpub. pas。这

7、样,就使他们可以通过定义这里有test6-1.dll 所要求在unitpub. pas中定义的类型和例程使用该DLL。,二、在公共单元,注意填写以下代码: 在interface部分: $IFNDEF Test6_1 /编译指令 function SumNum(An: word): word; StdCall; $ENDIF,7,在implementation部分: $IFNDEF Test6_1 Define the imported function 引入一个DLL例程的两种方法 /function SumNum(An: word): word; external test6_1.DLL i

8、ndex 1; 第一种方法 function SumNum(An: word): word; external test6_1.DLL name SumNum; 第二种方法 $ENDIF,8,exports SumNum; end.,三、导出的接口,查看实例6-1。,创建使用公共单元定义接口的Dll步骤: 1、通过向导生成Dll工程 2、定义访问接口 function SumNum(An: word): word; StdCall; 3、输出访问接口 exports /导出的接口 SumNum; end. 4、访问该Dll,9,6.3.1 创建静态连接的Dll(二),创建无模式窗体,步骤: 1

9、、声明输出接口 2、实现输出接口 注意:关于Tapplication的Handle 3、静态调用,10,1、创建一个Dll工程 2、给该工程添加一个窗体 3、在该窗体上拖放控件 4、在窗体类和implementation之间设置输出接口: function ExportFunctionName(AHandle: THandle; APara: SomeType): SomeType; stdCall; 可以声明多个 5、在implementation $R *.DFM后面编写该声明的实现: (1)D L L中的A p p l i c a t i o n对象与调用它的应用程序是分离的,为使D L

10、 L中的窗体真正成为应用程序模式窗体,必须将应用程序的句柄赋给D L L的A p p l i c a t i o n . H a n d l e属性。,11,Application.Handle := AHandle; (2)创建该窗体(非自动创建) Form1 := TForm.Create(Application); (3)实现 (4)调用Form的show方法。 6、在该工程的代码中填写(Uses子句与Begin之间) exports ExportFunctionName; 如有多个接口可以用“,”隔开。 7、专门创建一个新的应用程序调用该Dll. (1)在该应用程序的implement

11、ation之前,编写静态调用代码: function ExportFunctionName(AHandle: THandle; APara: SomeType): SomeType; StdCall; external DllName.DLL; (2)在该应用程序的使用部分直接使用该声明的函数。,12,8、调试该Dll: 设置该Dll的Run Parameters参数,详见实验指导书。,6-3,13,6.3.2、创建动态连接的Dll-模式窗体,1、创建一个Dll工程 2、给该工程添加一个窗体 3、在该窗体上拖放控件 4、在窗体类和implementation之间设置输出接口: function

12、 ExportFunctionName(AHandle: THandle; APara: SomeType): SomeType; stdCall; 可以声明多个 5、在implementation $R *.DFM后面编写该声明的实现: (1)D L L中的A p p l i c a t i o n对象与调用它的应用程序是分离的,为使D L L中的窗体真正成为应用程序模式窗体,必须将应用程序的句柄赋给D L L的A p p l i c a t i o n . H a n d l e属性。,14,Application.Handle := AHandle; (2)创建该窗体(非自动创建) Fo

13、rm1 := TForm.Create(Application); (3)实现 (4)调用Form的ShowModal方法。 (5)释放该窗体,调用Free方法。 6、在该工程的代码中填写(Uses子句与Begin之间) exports ExportFunctionName; 如有多个接口可以用“,”隔开。 7、专门创建一个新的应用程序调用该Dll. (1) First, define a procedural data type, this should reflect the procedure that is exported from the DLL. Type TShowString

14、 = function (AHandle: THandle; APara: SomeType): SomeType; StdCall; (2)在该应用程序的调用部分使用:,15,A:LoadLibrary函数: 在Windows单元声明的: function LoadLibrary; external kernel32 name LoadLibraryA; 该函数用来把指定的模块装入到内存。 语法: Function LoadLibrary(LibName :pChar):Thandle; 参数: LibName 为指定要装入的Dll文件名称,包含路径。 返回值: 函数执行成功,返回装载Dll

15、的实例句柄(该句柄传递给GetProcAddress和FreeLibrary),否则,返回错误代码。如在应用程序用LoadLibrary调用某一模块前,该模块已经装入,则LoadLibrary不会装载该模块的另一实例,但该模块的引用计数加1。,16,B:GetProcAddress函数 该函数功能是捡取给定模块中函数的地址。 语法: FunctionGetProcAddress(handle:Thandle;ProcName:PChar):TFarProc; 参数: Handle由LoadLibrary返回,包含被调用函数库模块的句柄; ProcName是指向含有函数名的字符串的指针,该函数名

16、与Exports部分公开的函数名称一致。 返回值: 成功,返回模块中函数入口处的地址; 失败,返回Nil.,17,C:FreeLibrary函数 该函数用来从内存中移出库模块。 语法: Procedure FreeLibrary(Handle :Thandle); 参数: Handle为库模块的句柄,由LoadLibrary返回; 由于库模块在内存中只装在一次,因而调用FreeLibrary首先使库模块的引用计数减1,直到为0时卸除该模块。,注意: 每调用一次LoadLibrary就应调用一次FreeLibrary,以保证不会有多余的库模块在应用程序结束后仍驻留内存,造成资源浪费和地址应用错误。,18,var LibHandle : THandle; SomeProc: TSomeProc; begin LibHand

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论