如何用delphi制作DLL动态库方法

合集下载

Delphi制作DLL的方法

Delphi制作DLL的方法

Delph‎i制作DL‎L的方法‎一 D‎l l的制作‎一般步骤‎二参数传‎递三 D‎L L的初始‎化和退出清‎理[如果需‎要初始化和‎退出清理]‎四全局‎变量的使用‎五调用‎静态载入‎六调用动‎态载入七‎在DLL‎建立一个T‎F orM‎八在DL‎L中建立一‎个TMDI‎C hild‎F orM‎九示例:‎十 De‎l phi制‎作的Dll‎与其他语言‎的混合编程‎中常遇问题‎:十一‎相关资料‎一 Dl‎l的制作一‎般分为以下‎几步:1‎在一个D‎L L工程里‎写一个过程‎或函数2‎写一个E‎x port‎s关键字,‎在其下写过‎程的名称。

‎不用写参数‎和调用后缀‎。

二参‎数传递1‎参数类型‎最好与wi‎n dow ‎C++的参‎数类型一致‎。

不要用D‎E LPHI‎的数据类型‎。

2 最‎好有返回值‎[即使是一‎个过程],‎来报出调用‎成功或失败‎,或状态。

‎成功或失败‎的返回值最‎好为1[成‎功]或0[‎失败].一‎句话,与w‎i ndow‎s c++‎兼容。

3‎用std‎c all声‎明后缀。

‎4最好大‎小写敏感。

‎5 无须‎用far调‎用后缀,那‎只是为了与‎w indo‎w s 16‎位程序兼容‎。

三‎D LL的初‎始化和退出‎清理[如果‎需要初始化‎和退出清理‎]1 D‎L LPro‎c[Sys‎U tils‎单元的一个‎P oint‎e r]是D‎L L的入口‎。

在此你可‎用你的函数‎替换了它的‎入口。

但你‎的函数必须‎符合以下要‎求[其实就‎是一个回调‎函数]。

如‎下:pr‎o cedu‎r e Dl‎l Ente‎r Poin‎t(dwR‎e ason‎: DWO‎R D);f‎a r;st‎d call‎;dwR‎e ason‎参数有四种‎类型:D‎L L_PR‎O CESS‎_ATTA‎C H:进程‎进入时D‎L L_PR‎O CESS‎_DETA‎C H:进程‎退出时D‎L L_TH‎R EAD_‎A TTAC‎H :线程‎进入时D‎L L_TH‎R EAD_‎D ETAC‎H :线程‎退出时在‎初始化部分‎写:‎D LLPr‎o c :=‎@DLL‎E nter‎P oint‎;D‎l lEnt‎e rPoi‎n t(DL‎L_PRO‎C ESS_‎A TTAC‎H);2‎如For‎m上有Td‎c omCo‎n nect‎i on组件‎,就Use‎s Act‎i vex,‎在初始化时‎写一句Co‎I niti‎a lize‎(nil‎);3 ‎在退出时一‎定保证Dc‎o mCon‎n ecti‎o n.Co‎n nect‎e d :=‎Fals‎e,并且数‎据集已关闭‎。

《Delphi程序设计基础教程》第11课:动态链接库入门

《Delphi程序设计基础教程》第11课:动态链接库入门

概述
学习目标
1、了解动态链接库 2、掌握编写动态链接库的方法 3、掌握调用DLL的方法 3 DLL 4、掌握编写Windows下的共享内存管理的方 法 5、掌握解决DLL中的异常方法 6、掌握调用约定的规则
/webnew/
概述
学习重点
1、编写动态链接库 2、调用DLL 3、DLL中的异常
/webnew/
调用DLL 调用DLL
1、静态调用 2、动态调用
/webnew/
小结
1、介绍静态调用的方法 2、介绍动态调用的方法
/webnew/
Windows下的共享内存管理 Windows下的共享内存管理
Delphi中的String类型很强大,普通的字符串长 度最大为256个字符,但Delphi中String类型 在默认情况下长度可以达到2 GB
/webnew/
小结
介绍Windows下的共享内存管理的方法
第11课 动态链接库入门 11课
(时间:1学时)
/webnew/
概述
本课内容
1、动态链接库简介 2、编写动态链接库 3、调用DLDLL中的异常 6、调用约定
/webnew/
小结
介绍解决DLL中异常的方法
/webnew/
调用约定
调用约定,是指调用程序时参数的传递顺序
/webnew/
小结
具体讲述一般调用约定时应满足的规则
/webnew/
/webnew/
DLL中的异常 DLL中的异常
当DLLs中发生一个运行时间错时,相应DLLs并 不一定从内存中移去(因为此时其他应用程序 可能正在用它),而是调用DLLs的程序异常中 止
/webnew/
学习难点

DELPHI中动态调用dll

DELPHI中动态调用dll

first unit in your library′s USES clause AND your project′s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
{$R *.res}
function GetDoubleExt(D:Double):Double ;stdcall;
begin
Result := D;
end;
function GetInt(I:Integer): Integer;stdcall;
begin
Image1.Picture.Assign(Table1Graphic);
Table1Graphic.Assign(Image1.Picture);
Exit;
DLLHandle := LoadLibrary(′DLLOne.dll′);
try
@Func := GetProcAddress(DLLHandle, ′GetDouble′);

DELPHI基础教程:动态链接库编程(一)[2]

DELPHI基础教程:动态链接库编程(一)[2]

DELPHI基础教程:动态链接库编程(一)[2]DLLs中的变量和段一个DLLs拥有自己的数据段(DS)因而它声明的任何变量都为自己所私有调用它的模块不能直接使用它定义的变量要使用必须通过过程或函数界面才能完成而对DLLs来说它永远都没有机会使用调用它的模块中声明的变量一个DLLs没有自己的堆栈段(SS)它使用调用它的应用程序的堆栈因此在DLL中的过程函数绝对不要假定DS = SS 一些语言在小模式编译下有这种假设但使用Delphi可以避免这种情况 Delphi绝不会产生假定DS = SS的代码 Delphi的任何运行时间库过程/函数也都不作这种假定需注意的是如果读者想嵌入汇编语言代码绝不要使SS 和DS登录同一个值DLLs中的运行时间错和处理由于DLLs无法控制应用程序的运行导致很难进行异常处理因此编写DLLs时要十分小心以确保被调用时能正常执行当DLLs中发生一个运行时间错时相应DLLs并不一定从内存中移去(因为此时其它应用程序可能正在用它)而调用DLLs的程序异常中止这样造成的问题是当DLLs已被修改重新进行调用时内存中保留的仍然可能是以前的版本修改后的程序并没有得到验证对于这个问题有以下两种解决方法在程序的异常处理部分显式将DLL卸出内存完全退出Windows 而后重新启动运行相应的程序同一般的应用程序相比 DLL中运行时间错的处理是很困难的而造成的后果也更为严重因此要求程序设计者在编写代码时要有充分周到的考虑库初始化代码的编写传统Windows中动态链接库的编写需要两个标准函数LibMain 和WEP 用于启动和关闭DLL 在LibMain中可以执行开锁DLL数据段分配内存初始化变量等初始化工作而WEP在从内存中移去DLLs前被调用一般用于进行必要的清理工作如释放内存等Delphi用自己特有的方式实现了这两个标准函数的功能这就是在工程文件中的begin…end部分添加初始化代码和传统Windows编程方法相比它的主要特色是初始化代码是可选的一些必要的工作(如开锁数据段)可以由系统自动完成所以大部分情况下用户不会涉及到可以设置多个退出过程退出时按顺序依次被调用LibMain和WEP对用户透明由系统自动调用初始化代码完成的主要工作是初始化变量分配全局内存块登录窗口对象等初始化工作在()节利用DLLs实现应用程序间的数据传输中用于数据共享的全局内存块就是在初始化代码中分配的设置DLLs退出时的执行过程Delphi有一个预定义变量ExitProc 用于指向退出过程的地址用户可以把自己的过程名赋给ExitProc 系统自动调用WEP函数把ExitProc指向的地址依次赋给WEP执行直到ExitProc为nil下边的一段程序包含一个退出过程和一段初始化代码用来说明如何正确设置退出过程library Test;{$S }uses WinTypes WinProcs;varSaveExit: Pointer;procedure LibExit; far;beginif ExitCode = wep_System_Exit thenbegin{ 系统关闭时的相应处理 }endelsebegin{ DLL卸出时的相应处理 }end;ExitProc := SaveExit; { 恢复原来的退出过程指针 }end;begin{DLL的初始化工作 }SaveExit := ExitProc; { 保存原来的退出过程指针 }ExitProc := @LibExit; { 安装新的退出过程 }end在初始化代码中首先把原来的退出过程指针保存到一个变量中而后再把新的退出过程地址赋给ExitProc 而在自定义退出过程LibExit结束时再把ExitProc的值恢复由于ExitProc是一个系统全局变量所以在结束时恢复原来的退出过程是必要的退出过程LibExit中使用了一个系统定义变量ExitCode 用于标志退出时的状态 ExitCode的取值与意义如下表 ExitCode的取值与意义━━━━━━━━━━━━━━━━━━━━━取值意义WEP_System_Exit Windows关闭WEP_Free_DLLx DLLs被卸出━━━━━━━━━━━━━━━━━━━━━退出过程编译时必须关闭stack_checking 因而需设置编译指示{$S }编写一般DLLs的应用举例在下面的程序中我们把一个字符串操作的函数储存到一个DLLs中以便需要的时候调用它应该注意的一点是为了保证这个函数可以被其它语言编写的程序所调用作为参数传递的字符串应该是无结束符的字符数组类型(即PChar类型)而不是Object Pascal的带结束符的Srting类型程序清单如下library Example;usesSysUtilsClasses;{返回字符在字符串中的位置}function InStr(SourceStr: PChar;Ch: Char) Integer; export;varLen i: Integer;beginLen := strlen(SourceStr)for i := to Len doif SourceStr[i] = ch thenbeginResult := i;Exit;end;Result := ;end;exportsInstr Index name MyInStr resident;beginend调用DLLs有两种方法可用于调用一个储存在DLLs中的过程lishixinzhi/Article/program/Delphi/201311/25208。

delphi创建DLL动态链接库(转载)

delphi创建DLL动态链接库(转载)

delphi创建DLL动态链接库(转载)delphi创建DLL动态链接库(转载)关键词:DLL动态链接库delphi编程Windows 的执行文件可以划分为两种形式程序和动态连接库(DLLs)。

一般程序运行是用.EXE文件,但应用程序有时也可以调用存储在DLL 中的函数。

当我们调用Windows 中的API 函数的时候,实际上就是调用存储在DLL 中的函数。

在如下几种情况下,调用DLL 是合理的:1)不同的程序使用相同的DLL ,这样只需要将DLL 在内存中装载一次,节省了内存的开销。

2)当某些内容需要升级的时候,如果使用DLL 只需要改变DLL 就可以了,而不需要把整个程序都进行变动。

3)由于DLL 是独立于语言的,所以,当不同语言习惯的人共同开发一个大型项目的时候,使用DLL 便于程序系统的交流,当然,Delphi开发的DLL 也可以在诸如Visual BASIC,C++ 等系统中使用。

下面通过几个例子,说明Delphi开发动态连接库的方法和规范。

第一节动态连接库的构建和调用方法一、动态连接库构建File---New---Other---DLL Wizard这就创建了一个动态连接库的基本模块library Project2;usesSysUtils,Classes;{$R *.res}beginend.把工程名改为Mydll,并写入必要的函数library mydll;usesSysUtils,Classes,Dialogs,windows;function Triple(N:Integer):integer;stdcall;beginresult:=N+3;end;function Double(N:Integer):integer;stdcall;beginresult:=N+2;end;function Triple1(N:Integer):integer;stdcall;beginshowmessage('计算N+3');result:=N+3;end;function Double1(N:Integer):integer;stdcall;beginmessagebox(0,'计算N+2','计算N+2',mb_ok);result:=N+2;end;exportsTriple name 'Tr',Double name 'Do',Triple1 name 'TrM',Double1 name 'DoM';Triple,Double,Triple1,Double1;{$R *.RES}beginend.其中函数:Triple:把传入值加三Double:把传入值加二Triple1:把传入值加三并显示提示Double1:把传入值加二并显示提示从这个例子中可以看出DLL 程序的几个规则:1)在DLL 程序中,输出函数必须被声明为stdcall,以使用标准的Win32 参数传递技术来代替优化的Register。

Delphi环境中编写调用DLL的方法和技巧

Delphi环境中编写调用DLL的方法和技巧

第一章为什么要使用动态链接库(DLL) top提起DLL您一定不会陌生,在Windows中有着大量的以DLL为后缀的文件,它们是保证Windows正常运行和维护升级的重要保证。

(举个例子,笔者的Win95 System目录下尽有500多个DLL文件。

)其实,DLL 是一种特殊的可执行文件。

说它特殊主要是因为一般它都不能直接运行,需要宿主程序比如*.EXE程序或其他DLL的动态调用才能够使用。

简单的说,在通常情况下DLL是经过编译的函数和过程的集合。

使用DLL技术主要有以下几个原因:一、减小可执行文件大小。

DLL技术的产生有很大一部分原因是为了减小可执行文件的大小。

当操作系统进入Windows时代后,其大小已经达到几十兆乃至几百兆。

试想如果还是使用DOS时代的单执行文件体系的话一个可执行文件的大小可能将达到数十兆,这是大家都不能接受的。

解决的方法就是采用动态链接技术将一个大的可执行文件分割成许多小的可执行程序。

二、实现资源共享。

这里指的资源共享包括很多方面,最多的是内存共享、代码共享等等。

早期的程序员经常碰到这样的事情,在不同的编程任务中编写同样的代码。

这种方法显然浪费了很多时间,为了解决这个问题人们编写了各种各样的库。

但由于编程语言和环境的不同这些库一般都不能通用,而且用户在运行程序时还需要这些库才行,极不方便。

DLL的出现就像制定了一个标准一样,使这些库有了统一的规范。

这样一来,用不同编程语言的程序员可以方便的使用用别的编程语言编写的DLL。

另外,DLL还有一个突出的特点就是在内存中只装载一次,这一点可以节省有限的内存,而且可以同时为多个进程服务。

三、便于维护和升级。

细心的朋友可能发现有一些DLL文件是有版本说明的。

(查看DLL文件的属性可以看到,但不是每一个DL L文件都有)这是为了便于维护和升级。

举个例子吧,早期的Win95中有一个BUG那就是在闰年不能正确显示2月29日这一天。

后来,Microsoft发布了一个补丁程序纠正了这个BUG。

用Delphi编写及调用DLL的方法和技巧

用Delphi编写及调用DLL的方法和技巧
蒋红龙
【期刊名称】《电脑开发与应用》
【年(卷),期】2003(016)012
【摘要】动态链接库是一种特殊的可执行文件,它是Microsoft Windows系列操作系统的一项新技术,阐述了动态链接库的基本概念及其优点,并举例讨论了用Delphi编写和调用DLL.的方法和技巧,由于DLL具有节省内存、共享代码、升级方便和独立于编程语言的优点,现已被广泛应用.
【总页数】3页(P22-24)
【作者】蒋红龙
【作者单位】大庆有限责任公司第四采油厂,大庆,163000
【正文语种】中文
【中图分类】TP3
【相关文献】
1.在C++Builder中编写和调用DLL [J], 黄明志
2.如何利用Delphi 4编写网上检索馆藏数据库的ISAPL DLL [J], 马林梓
3.使用Delphi编写DLL实现软件自动更新 [J], 云凤生
4.在VC中对Delphi所生成的DLLs的调用 [J], 李强;贾云霞
5.在Delphi中调用由VC++生成DLL的方法 [J], 赵福来;娄国焕
因版权原因,仅展示原文概要,查看原文内容请购买。

Delphi数据库的动态建立

Delphi数据库的动态建立delphi 最吸引人的特点之一就是它的强大的数据库访问能力通过database desktop 工具可方便的建立编辑数据库由于实际原因我们往往需要在程序运行状态下动态建立某个数据库如果你让用户用database desktop 工具手工建立数据表那么你写的程序将会打大折扣不过你不用担心delphi完全可以用语言来完成此功能为我们提供方便我在学习和实践中总结出两种方法我叫做table 法和sql法下面通过简单的实例来描述动态数据库建立的过程一 Table方法(以建立paradox数据表为例假设库名为ljh db)新建一工程文件zhoudf dpr 在unit 中的uses语句中加入db dbtables单元在面板上选取button元件置于form 表中双击button 输入如下代码Procedure Tform Button Click(Sender: Tobject);var table :ttable; begin table :=ttable create(self);with table do begin active:=false;tablename:= ljh db ;tabletype:=ttparadox; with fielddefs do {此方法为ljh db增加字段} begin clear;add( yj ftdate false);add( zp ftstring false); {增加具体的字段名类型}add( zdm ftinteger false);end;With indexdefs do {此方法为ljh db增加索引字段} Begin Clear;Add( yjindex yj [ixprimary]);end;createtable;end;end;二 sql方法在面板上选取button元件置于form 表中双击button 输入如下代码Procedure Tform Button Click(Sender: Tobject);var table :tquery; begin table :=tquery create(self);with table do begin with sql do begin clear;add( create table ljh db );add( (yj date ); {注意引号中的( }add( zp char( ) );add( zdm int) ); {注意引号中的)}end;execsql;sql clear;sql add( create index yj on ljh db (yj) ); {此sql语句为ljh db 增加索引字段}execsql;end;end;lishixinzhi/Article/program/Delphi/201311/24746。

Delphi动态与静态调用DLL(最好的资料)

Delphi动态与静态调用DLL(最好的资料)摘要:本文阐述了 Windows 环境下动态链接库的概念和特点,对静态调用和动态调用两种调用方式作出了比较,并给出了 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 的一份映像。

如何用delphi制作DLL动态库方法

用Delphi制作DLL的方法一Dll的制作一般步骤二参数传递三DLL的初始化和退出清理[如果需要初始化和退出清理]四全局变量的使用五调用静态载入六调用动态载入七在DLL建立一个TForM八在DLL中建立一个TMDIChildForM九示例:十Delphi制作的Dll与其他语言的混合编程中常遇问题:十一相关资料一Dll的制作一般分为以下几步:1 在一个DLL工程里写一个过程或函数2 写一个Exports关键字,在其下写过程的名称。

不用写参数和调用后缀。

二参数传递1 参数类型最好与window C++的参数类型一致。

不要用DELPHI的数据类型。

2 最好有返回值[即使是一个过程],来报出调用成功或失败,或状态。

成功或失败的返回值最好为1[成功]或0[失败].一句话,与windows c++兼容。

3 用stdcall声明后缀。

4 最好大小写敏感。

5 无须用far调用后缀,那只是为了与windows 16位程序兼容。

三DLL的初始化和退出清理[如果需要初始化和退出清理]1 DLLProc[SysUtils单元的一个Pointer]是DLL的入口。

在此你可用你的函数替换了它的入口。

但你的函数必须符合以下要求[其实就是一个回调函数]。

如下:procedure DllEnterPoint(dwReason: DWORD);far;stdcall;dwReason参数有四种类型:DLL_PROCESS_ATTACH:进程进入时DLL_PROCESS_DETACH进程退出时DLL_THREAD_A TTACH 线程进入时DLL_THREAD_DETACH 线程退出时在初始化部分写:DLLProc := @DLLEnterPoint;DllEnterPoint(DLL_PROCESS_ATTACH);2 如Form上有TdcomConnection组件,就Uses Activex,在初始化时写一句CoInitialize (nil);3 在退出时一定保证DcomConnection.Connected := False,并且数据集已关闭。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用Delphi制作DLL的方法一Dll的制作一般步骤二参数传递三DLL的初始化和退出清理[如果需要初始化和退出清理]四全局变量的使用五调用静态载入六调用动态载入七在DLL建立一个TForM八在DLL中建立一个TMDIChildForM九示例:十Delphi制作的Dll与其他语言的混合编程中常遇问题:十一相关资料一Dll的制作一般分为以下几步:1 在一个DLL工程里写一个过程或函数2 写一个Exports关键字,在其下写过程的名称。

不用写参数和调用后缀。

二参数传递1 参数类型最好与window C++的参数类型一致。

不要用DELPHI的数据类型。

2 最好有返回值[即使是一个过程],来报出调用成功或失败,或状态。

成功或失败的返回值最好为1[成功]或0[失败].一句话,与windows c++兼容。

3 用stdcall声明后缀。

4 最好大小写敏感。

5 无须用far调用后缀,那只是为了与windows 16位程序兼容。

三DLL的初始化和退出清理[如果需要初始化和退出清理]1 DLLProc[SysUtils单元的一个Pointer]是DLL的入口。

在此你可用你的函数替换了它的入口。

但你的函数必须符合以下要求[其实就是一个回调函数]。

如下:procedure DllEnterPoint(dwReason: DWORD);far;stdcall;dwReason参数有四种类型:DLL_PROCESS_ATTACH:进程进入时DLL_PROCESS_DETACH进程退出时DLL_THREAD_A TTACH 线程进入时DLL_THREAD_DETACH 线程退出时在初始化部分写:DLLProc := @DLLEnterPoint;DllEnterPoint(DLL_PROCESS_ATTACH);2 如Form上有TdcomConnection组件,就Uses Activex,在初始化时写一句CoInitialize (nil);3 在退出时一定保证DcomConnection.Connected := False,并且数据集已关闭。

否则报地址错。

四全局变量的使用在widnows 32位程序中,两个应用程序的地址空间是相互没有联系的。

虽然DLL在内存中是一份,但变量是在各进程的地址空间中,因此你不能借助dll的全局变量来达到两个应用程序间的数据传递,除非你用内存映像文件。

五调用静态载入1 客户端函数声名:1)大小写敏感。

2)与DLL中的声明一样。

如:showform(form:Tform);Far;external'yproject_dll.dll';3)调用时传过去的参数类型最好也与windows c++一样。

4)调用时DLL必须在windows搜索路径中,顺序是:当前目录;Path路径;windows;widows\system;windows\ssystem32;六调用动态载入1 建立一种过程类型[如果你对过程类型的变量只是一个指针的本质清楚的话,你就知道是怎么回事了]。

如:typemypointer=procedure(form:Tform);Far;external;varHinst:Thandle;showform:mypointer;beginHinst:=loadlibrary('yproject_dll');//Load一个Dll,按文件名找。

showform:=getprocaddress(Hinst,'showform');//按函数名找,大小写敏感。

如果你知道自动化对象的本质就清楚了。

showform(application.mainform);//找到函数入口指针就调用。

Freelibrary(Hinst);end;七在DLL建立一个TForM1 把你的Form Uses到Dll中,你的Form用到的关联的单元也要Uses进来[这是最麻烦的一点,因为你的Form或许Uses了许多特殊的单元或函数]2 传递一个Application参数,用它建立Form.八在DLL中建立一个TMDIChildForM1 Dll中的MDIForm.FormStyle不用为fmMDIChild.2 在CreateForm后写以下两句:function ShowForm(mainForm:TForm):integer;stdcallvarForm1: TForm1;ptr:PLongInt;beginptr:=@(Application.MainForm);//先把dll的MainForm句柄保存起来,也无须释放,只不过是替换一下ptr^:=LongInt(mainForm);//用主调程序的mainForm替换DLL的MainForm。

MainForm是特殊的WINDOW,它专门管理Application中的Forms资源.//为什么不直接Application.MainForm := mainForm,因为Application.MainForm是只读属性Form1:=TForm1.Create(mainForm);//用参数建立end;备注:参数是主调程序的Application.MainForm九示例:DLL源代码:library Project2;usesSysUtils,Classes,Dialogs,Forms,Unit2 in 'Unit2.pas' {Form2};{$R *.RES}varccc: Pchar;procedure OpenForm(mainForm:TForm);stdcall;varForm1: TForm1;ptr:PLongInt;beginptr:=@(Application.MainForm);ptr^:=LongInt(mainForm);Form1:=TForm1.Create(mainForm);end;procedure InputCCC(Text: Pchar);stdcall;beginccc := Text;end;procedure ShowCCC;stdcall;beginShowMessage(String(ccc));end;exportsOpenForm;InputCCC,ShowCCC;beginend.调用方源代码:unit Unit1;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;Button2: TButton;Edit1: TEdit;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}procedure OpenForm(mainForm:TForm);stdcall;External'project2.dll'; procedure ShowCCC;stdcall;External'project2.dll';procedure InputCCC(Text: Pchar);stdcall;External'project2.dll';procedure TForm1.Button1Click(Sender: TObject);varText: Pchar;beginText := Pchar(Edit1.Text);// OpenForm(Application.MainForm);//为了调MDICHILDInputCCC(Text);//为了实验DLL中的全局变量是否在各个应用程序间共享end;procedure TForm1.Button2Click(Sender: TObject);beginShowCCC;//这里表明WINDOWS 32位应用程序DLL中的全局变量也是在应用程序地址空间中,16位应用程序或许不同,没有做实验。

end;十Delphi制作的Dll与其他语言的混合编程中常遇问题:1 与PowerBuilder混合编程在定义不定长动态数组方面在函数退出清理堆栈时老出现不可重现的地址错,原因未明,大概与PB的编译器原理有关,即使PB编译成二进制代码也如此。

Windows 的执行文件可以划分为两种形式程序和动态连接库(DLLs)。

一般程序运行是用.EXE文件,但应用程序有时也可以调用存储在DLL 中的函数。

当我们调用Windows 中的API 函数的时候,实际上就是调用存储在DLL 中的函数。

在如下几种情况下,调用DLL 是合理的:1)不同的程序使用相同的DLL ,这样只需要将DLL 在内存中装载一次,节省了内存的开销。

2)当某些内容需要升级的时候,如果使用DLL 只需要改变DLL 就可以了,而不需要把整个程序都进行变动。

3)由于DLL 是独立于语言的,所以,当不同语言习惯的人共同开发一个大型项目的时候,使用DLL 便于程序系统的交流,当然,Delphi开发的DLL 也可以在诸如Visual BASIC,C++ 等系统中使用。

下面通过几个例子,说明Delphi开发动态连接库的方法和规范。

第一节动态连接库的构建和调用方法一、动态连接库构建File---New---Other---DLL Wizard这就创建了一个动态连接库的基本模块library Project2;usesSysUtils,Classes;{$R *.res}beginend.把工程名改为Mydll,并写入必要的函数library mydll;usesSysUtils,Classes,Dialogs,windows;function Triple(N:Integer):integer;stdcall; beginresult:=N+3;end;function Double(N:Integer):integer;stdcall; beginresult:=N+2;end;function Triple1(N:Integer):integer;stdcall; beginshowmessage('计算N+3');result:=N+3;end;function Double1(N:Integer):integer;stdcall; beginmessagebox(0,'计算N+2','计算N+2',mb_ok);result:=N+2;end;exportsTriple name 'Tr',Double name 'Do',Triple1 name 'TrM',Double1 name 'DoM';Triple,Double,Triple1,Double1;{$R *.RES}beginend.其中函数:Triple:把传入值加三Double:把传入值加二Triple1:把传入值加三并显示提示Double1:把传入值加二并显示提示从这个例子中可以看出DLL 程序的几个规则:1)在DLL 程序中,输出函数必须被声明为stdcall,以使用标准的Win32 参数传递技术来代替优化的Register。

相关文档
最新文档