如何用delphi制作DLL动态库方法_第1页
如何用delphi制作DLL动态库方法_第2页
如何用delphi制作DLL动态库方法_第3页
如何用delphi制作DLL动态库方法_第4页
如何用delphi制作DLL动态库方法_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

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

文档简介

1、用Delphi制作DLL的方法一 Dll的制作一般步骤二参数传递三DLL的初始化和退出清理如果需要初始化和退出清理四全局变量的使用五调用静态载入六调用动态载入七在DLL建立一个 TForM八在DLL中建立一个TMDIChildForM九示例:十Delphi制作的Dll与其他语言的混合编程中常遇问题: 十一相关资料 一 Dll的制作一般分为以下几步:1在一个DLL工程里写一个过程或函数2写一个Exports关键字,在其下写过程的名称。不用写参数和调用后缀。二参数传递1参数类型最好与 window C+的参数类型一致。不要用 DELPHI的数据类型。2最好有返回值即使是一个过程,来报出调用成功或失

2、败,或状态。成功或失败的返回值 最好为1成功或0失败一句话,与 windows C+兼容。3用stdcall声明后缀。4最好大小写敏感。5无须用far调用后缀,那只是为了与windows 16位程序兼容。三DLL的初始化和退出清理如果需要初始化和退出清理 1 DLLProcSysUtils单元的一个 Pointer是DLL的入口。在此你可用你的函数替换了它的入口。但你的函数必须符合以下要求其实就是一个回调函数。如下:procedure DllE nterPoi nt(dwReaso n: DWORD);far;stdcall;dwReason参数有四种类型:DLL_PROCESS_ATTACH

3、:进程进入时DLL_PROCESS_DETACH 进程退出时DLL_THREAD_A TTACH 线程进入时DLL_THREAD_DETACH线程退出时在初始化部分写:DLLProc := DLLE nterPoi nt;DllE nterPoi nt(DLL_PROCESS_ATTACH);2 女口 Form 上有 TdcomConnection 组件,就 Uses ActiveX,在初始化时写一句 Colnitialize (nil);3在退出时一定保证 DcomConnection.Connected := False,并且数据集已关闭。否则报地址错。四全局变量的使用在widnows 3

4、2位程序中,两个应用程序的地址空间是相互没有联系的。虽然DLL在内存中是一份,但变量是在各进程的地址空间中,因此你不能借助dll的全局变量来达到两个应用程序间的数据传递,除非你用内存映像文件。五调用静态载入1客户端函数声名:1) 大小写敏感。2) 与DLL中的声明一样。女口:showform(form:Tform);Far;externalyproject_dll.dll:3) 调用时传过去的参数类型最好也与win dows C+ 一样。4) 调用时DLL必须在 win dows搜索路径中,顺序是:当前目录;Path路径;wi ndows;widowssystem;wi ndowsssyste

5、m32;六调用动态载入1建立一种过程类型如果你对过程类型的变量只是一个指针的本质清楚的话,你就知道是 怎么回事了 。如:typemypoi nter=procedure(form:Tform);Far;external;varHin st:Tha ndle;showform:mypo in ter;beginHinst:=loadlibrary(yproject_dll);/Load一个 Dll,按文件名找。showform:=getprocaddress(Hinst,showform);按函数名找,大小写敏感。如果你知道自动化 对象的本质就清楚了。showform(application.m

6、ainform);/ 找到函数入口指针就调用。Freelibrary(Hi nst);en d;七在DLL建立一个 TForM1把你的Form Uses到Dll中,你的Form用到的关联的单元也要Uses进来这是最麻烦的一点,因为你的Form或许Uses 了许多特殊的单元或函数2传递一个 Application参数,用它建立 Form.八在DLL中建立一个TMDIChildForM1 Dll 中的 MDIForm.FormStyle 不用为 fmMDIChild.2在CreateForm后写以下两句:function ShowForm(ma inFo rm:TForm):i nteger;st

7、dcallvarForm1: TForm1;ptr:PL onglnt;beginptr:=(Applicati on .Mai nForm);/ 先把dll的Mai nForm 句柄保存起来,也无须释放,只不过是 替换一下ptrA:=Lo ngl nt(ma in Form);/ 用主调程序的 mai nF orm 替换 DLL 的 Mai nForm。 Ma in Form 是特 殊的 WINDOW,它专门管理 Application中的Forms资源./为什么不直接 Application.MainForm := mainForm, 因为 Application.MainForm 是只读

8、属性 Form1:=TForm1.Create(mainForm); 用参数建立en d;备注:参数是主调程序的Applicati on .Mai nForm九示例:DLL源代码:library Project2;usesSysUtils,Classes,Dialogs,Forms,Unit2 in U ni t2.pas Form2;$R *.RESvarccc: Pchar;procedure OpenFo rm(ma inFo rm:TForm);stdcall;varForm1: TForm1;ptr:PL onglnt;beginptr:=(Applicati on.MainFo r

9、m);ptrA:=L on gl nt(mai nF orm);Form1:=TForm1.Create(mai nF orm);en d;procedure In putCCC(Text: Pchar);stdcall;beginccc := Text;en d;procedure ShowCCC;stdcall;beginShowMessage(Stri ng(ccc);en d;exportsOpenForm;In putCCC,ShowCCC;beginen d.调用方源代码:unit Uni t1;in terfaceusesWin dows. Messages, SysUtils,

10、 Classes, Graphics, Con trols, Forms, Dialogs, StdCtrls;typeTForm1 = class(TForm)Butto n1: TButt on;Butto n2: TButt on;Edit1: TEdit;procedure Butto n1Click(Se nder: TObject);procedure Butto n2Click(Se nder: TObject);private Private declarati ons public Public declarati ons en d;varForm1: TForm1;impl

11、eme ntati on$R *.DFMprocedure OpenFo rm(ma inFo rm:TForm);stdcall;Exter nalproject2.dll: procedure ShowCCC;stdcall;Exter nalproject2.dll:procedure In putCCC(Text: Pchar);stdcall;Externalproject2.dll:procedure TForm1.Butt on 1Click(Se nder: TObject);varText: Pchar;beginText := Pchar(Edit1.Text);/ Ope

12、 nForm(Applicatio n. Mai nF orm); 为了调 MDICHILDInputCCC(Text);/为了实验DLL中的全局变量是否在各个应用程序间共享 en d;procedure TForml.Butt on 2Click(Se nder: TObject);beginShowCCC;/这里表明WINDOWS 32位应用程序DLL中的全局变量也是在应用程序地址空 间中,16位应用程序或许不同,没有做实验。en d;十Delphi制作的Dll与其他语言的混合编程中常遇问题:1与PowerBuilder混合编程在定义不定长动态数组方面在函数退出清理堆栈时老出现不可重现的地

13、址错,原因未明,大概与PB的编译器原理有关,即使PB编译成二进制代码也如此。Windows的执行文件可以划分为两种形式程序和动态连接库(DLLs)。一般程序运行是用.EXE文件,但应用程序有时也可以 调用存储在DLL中的函数。当我们调用 Windows中的API函数的时候,实际上就是调用 存储在DLL中的函数。在如下几种情况下,调用DLL是合理的:1) 不同的程序使用相同的DLL,这样只需要将 DLL在内存 中装载一次,节省了内存的开销。2) 当某些内容需要升级的时候,如果使用DLL只需要改变 DLL就可以了,而不需要把整个程序都进行变动。3)由于DLL是独立于语言的,所以,当不同语言习惯的人

14、共同开发一个大型项目的时候,使用DLL便于程序系统的交流,当然,Delphi开发的DLL也可以在诸如Visual BASIC,C+等系 统中使用。下面通过几个例子,说明Delphi开发动态连接库的方法和规范。第一节动态连接库的构建和调用方法一、动态连接库构建File-New-Other-DLL Wizard这就创建了一个动态连接库的基本模块library Project2;usesSysUtils,Classes;$R *.resbeginen d.把工程名改为Mydll,并写入必要的函数library mydll;usesSysUtils,Classes,Dialogs,w in dows;

15、fun ctio n Triple(N:l nteger):i nteger;stdcall;beginresult:=N+3;en d;fun ctio n Double(N:I nteger):i nteger;stdcall;beginresult:=N+2;en d;function Triple1(N:I nteger):i nteger;stdcall;beginshowmessage(计算 N+3); result:=N+3;en d;function Double1(N:I nteger):i nteger;stdcall;beginmessagebox(0,计算 N+2,计算

16、 N+2,mb_ok); result:=N+2;en d;exportsTriple n ame Tr,Double n ame Do,Triple1 name TrM,Double1 n ame DoM;Triple,Double,Triple1,Double1;$R *.RESbeginen d.其中函数:Triple :把传入值加三Double :把传入值加二Triplel :把传入值加三并显示提示 Doublel :把传入值加二并显示提示从这个例子中可以看出DLL程序的几个规则:1) 在DLL程序中,输出函数必须被声明为stdcall,以使用标准的Win32参数传递技术来代替优化的R

17、egister。(说明:在Delphi中Register方式是缺省的调用约定,这个约 定尽量采用寄存器来传递参数,传递次序从左到右,最多可用到3个CPU的寄存器,如果参数多于3个,剩下的就通过栈来传送,使用寄存器传送可保证参数传递的速度最快。而stdcall方式是通过 Windows的标准调用来传递参数,传递 秩序从左到右,这种方式适合调用Windows的API ,在DLL中,当然要使用这种方式)。2) 所有的输出函数都必须列在exports子句下面,这使的子例程 在DLL外部就可以看到。exportsTriple n ame Tr,Double n ame Do,Triple1 name T

18、rM,Double1 n ame DoM;列出了用户使用这个函数的接口名字。虽然别名不是必须的,但 最好给个别名,以便用户程序更容易找到这个函数,同时还要指出,Delphi 6.0取消了 Delphi 5.0中允许使用的index,如果还用Index 来指明接口名字,Delphi 6.0中将提示错误。实例中给出了两种提示方法,主要想说明一个问题:showmessage(),是VCL提供的函数,由于多次编译VCL,做出的程序会比较大。而 messagebox(0,mb_ok) 是 Windows 提供的 API 函数,做 出的程序会比较小。这就是说,编写 DLL程序的时候,要尽量避免多次编译VC

19、L。作为一个实例,这里把两种方法都列出来了。保存编译:Projrct-Build Mydll这就完成了一个简单的动态连接库的编写。二、动态连接库的调用首先在implementation下做调用声明con stgdi32=mydll.dll:fun ctio n triple( n:in teger):i nteger;stdcall;external gdi32 n ame Tr: fun ctio n Double(N:l nteger):i nteger;stdcall;external gdi32 n ame Do; fun ctio n triple1( n:in teger):i n

20、teger;stdcall;external gdi32 n ame TrM; function Double1(N:I nteger):i nteger;stdcall;exter nal gdi32 n ame DoM;以后程序中就可以作为普通的函数使用了,例如:procedure TForm1.Butt on 1Click(Se nder: TObject); var N:i nteger;beginN:=updow n1.positi on;edit1.text:=i nttostr(triple(N); en d;第二节 DLL中的Delphi窗体一、在DLL中放置窗的的方法在DLL

21、中,除了放置标准的函数和过程以外,也可以放置 已经做好的的delphi窗体,也可以把做好的窗体供其它程序使 用,方法是:1) 首先按普通方法制作窗体,不过在in terface区域,对接口函数做如下声明function Createform(capt:stri ng):stri ng;stdcall;2 )在implementation下加入接口函数function Createform(capt:stri ng):stri ng;stdcall;var Forml: TForml;beginform1:=Tform1.Create(applicatio n);form1.show;form1

22、.capti on:=capt;en d;3) 制作DLL动态连接库,但要声明:usesun it1 in un it1.pas:exports写入接口标示符Createform n ame Myform;4) 调用窗体的程序按普通方法制作,但是在implementation下首 先声明要调用的 DLL函数con stgdi32=myFormdll.dll:fun ctio n Createform(capt:stri ng):stri ng;stdcall;external gdi32 n ame Myform;procedure TForm3.Butt on 1Click(Se nder:

23、 TObject);var n, m:stri ng;beginm:=我的窗体;Createform(m);var n,m:stri ng;en d;二、DLL中的调用窗体时的数据传递在窗体调用时,可以用普通的函数方法传递数据,下面举 个例子。1)建立窗体做一个改变颜色窗体,放在DLL中,可以用普通的方法来做,但要作如下声明:fun ctio n mycolor(col:lo ngin t):l ongin t;stdcall;function Getcolor:l ongin t;stdcall;其中,mycolor为构造窗体;Getcolor为传递颜色数据。在implementation区

24、声明一个窗体内全局的变量var color1:l ongint;下面写出相应的程序fun ctio n mycolor(col:l on gi nt):lo ngin t;stdcall;var Form1: TForm1;beginform1:=Tform1.Create(applicatio n);form1.show;form1.pa nel1.Color:=col;form1.edit1.Text:=in ttostr(form1.pa nel1.Color);result:=color1;en d;function Getcolor:l ongin t;stdcall;beginresult:=color1;en d;procedure

温馨提示

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

评论

0/150

提交评论