[转]Delphi DLL的创建、静态 以及动态调用
第一章 DLL简单介绍
由于在目前的学习工作中,需要用到DLL文件,就学习了下,在这里作个总结。
首先装简单介绍下DLL:
1,减小可执行文件的大小
DLL技术的产生有很大一部分原因是为了减小可执行文件的大小。当操作系统进入Windows时代后,其大小已经达到几十兆乃至几百兆。试想如果还是使用DOS时代的单执行文件体系的话一个可执行文件的大小可能将达到数十兆,这是大家都不能接受的。解决的方法就是采用动态链接技术将一个大的可执行文件分割成许多小的可执行程序。
2,实现资源共享
这里指的资源共享包括很多方面,最多的是内存共享、代码共享等等。DLL还有一个突出的特点就是在内存中只装载一次,这一点可以节省有限的内存,而且可以同时为多个进程服务。
3,便于维护和升级
在软件运行出现问题的时候,我们并不需要重新安装程序,只需要替换相应的DLL文件即可。
4,比较安全
这里说的安全也包括很多方面。比如,DLL文件遭受病毒的侵害机率要比普通的EXE文件低很多。另外,由于是动态链接的,这给一些从事破坏工作的“高手”们多少带来了一些反汇编的困难。
第二章 在Delphi中编写DLL文件
编写DLL文件其实不是什么困难的事情,和我们平时在Delphi中编写程序基本相似,下面先以一个简单的例子来说明。
- library DLL;
- { Important note about DLL memory management: ShareMem must be the
- 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
- with your DLL. To avoid using BORLNDMM.DLL, pass string information
- using PChar or ShortString parameters. }
- uses
- ShareMem,
- SysUtils,
- Classes;
- function testStr: TStringList; stdcall;
- var
- str: string;
- strlist: TStringList;
- begin
- strlist := TStringList.Create;
- strlist.Add('hello');
- strlist.Add('world');
- str := 'hello world';
- result := strlist;
- end;
- function testInt(i: Integer): Integer; stdcall;
- begin
- Inc(i);
- result := i;
- end;
- {$R *.res}
- exports
- testStr,
- testInt;
- begin
- end.
可以看出在上面的Dll文件中我们封装了两个函数。跟一般Delphi编写的程序基本相同,只是在DLL文件中的函数后面多了一个stdcall参数,并且用exports声明需要引出的函数。只要编译上述代码就可以得到一个动态链接库的Dll文件。
1,在Dll中编写的函数必须在后面加上stdcall调用参数,如果忘记添加stdcall参数的话虽然编译可以通过,但在调用这个DLL时会出现很严重的错误,导致操作系统的死锁。
2,所写的函数和过程必须用exports声明为外部函数。若没有声明,那Dll内部的函数是不可调用的,这一点显然不是我们想看到的。
3,当使用了长字符串类型的参数、变量时,如string,要引用ShareMem。虽然Delphi中的string功能很强大,但若是您编写的Dll文件要供其它编程语言调用时,最好使用PChar类型。如果您要坚持使用string类型的参数时、变量甚至是记录信息时,就要引用ShareMem单元,而且这个单元必须是第一个引用的,即在uses语句后的第一个单元。如下:
- uses
- ShareMem,
- SysUtils,
- Classes;
另外,还有一个地方我们需要添加ShareMem单元,即在您的工程文件中(*.dpr)中的uses下第一个引用ShareMem单元。这里需要注意的是在*.dpr文件中而不是单元文件(*.pas)中添加相同的单元,这一点Delphi自带的帮助文件没有说清楚,造成了许多误会。若不这样做的话,您可能付出死机的代价。避免使用string类型的方法是将其转换为PChar或ShortString类型。
第三章 Dll文件的调用
一,静态调用
调用Dll文件要比编写Dll容易多了,这里先总结一下Dll的静态调用。首先看下面的小例子:
- function testInt(i: Integer): Integer; stdcall; external 'DLL.dll';
- procedure TForm1.btn2Click(Sender: TObject);
- begin
- showMessage(inttostr(testInt(1)));
- end;
大家可以看到我们做的唯一的工作是将Dll中的函数说明放在implementation下(或是放在文件单元的var下),并且用external语句指定了Dlll的位置。这样我们就可以直接使用Dll中的函数了。
1,调用参数stdcall,在引用Dll中的函数时也要使用stdcalll参数。
2,用external声明Dll文件的位置。注意文件的后缀名必须加上。
3,不能从Dll中调用全局变量。如果我们在DLL中声明了某种全局变量,如:var s:byte 。这样在DLL中s这个全局变量是可以正常使用的,但s不能被调用程序使用,既s不能作为全局变量传递给调用程序。不过在调用程序中声明的变量可以作为参数传递给DLL。
二,动态调用
动态调用Dll文件要复杂很多,但非常灵活。在运行大的程序时可以节省内存空间。我们看下面的例子:
- procedure TForm1.btn1Click(Sender: TObject);
- type
- Taddc = function: TStringList; stdcall;
- var
- hh: THandle;
- addc: Taddc;
- temp: TStringList;
- i: Integer;
- begin
- hh := LoadLibrary('DLL.dll');
- try
- if hh <> 0 then
- @addc := GetProcAddress(hh, PChar('testStr'));
- if not (@addc = nil) then
- begin
- temp := addc;
- for i := 0 to temp.Count - 1 do
- showMessage(temp[i]);
- end
- else
- begin
- RaiseLastWin32Error;
- end;
- finally
- FreeLibrary(hh);
- end;
- end;
由上面代码可以看到,这种动态调用技术很复杂。但只要更改参数就可动态更改所调用Dll文件的名字。
1,在type中定义所要调用的函数或过程的类型,在这里同样也要加上stdcall参数。
2,释放Dll。在上面程序中我们使用LoadLibray函数加载了dll文件,在使用完Dll文件时切记调用FreeLibrary函数来释放Dll,否则Dll将会一直占用你的内存直至您退出Windows或是关机为止。在这里需要注意的是要确保在释放dll的时候没有任何指针指向该dll中所定义的变量、过程等,否则无法正常释放,招聘访问冲突异常。或是导致程序出现空指针,导致程序意外中止。
3,在动态调用的Dll函数中我们使用了string类型,由于在两处文件内都引用了ShareMem,所以string类型的数据可以正使用,以及作为参数来传递。
三,静态和动态调用的对比
1,静态方法实现简单,易于掌握。并且一般来说速度比较快,也更加安全可靠一些。但静态方法不能灵活地在运行时装卸所需的Dll,而主程序在开始运行时就装载了Dll只到程序结束时才释放该Dll。
2,动态方法很好地解决了静态方法中的不足,可以方便的访问Dll中的函数和过程。但动态方法难以完全掌握,使用时因为不同的函数或过程需要定义很多复杂的类型和调用方法。
[转]Delphi DLL的创建、静态 以及动态调用的更多相关文章
- Delphi DLL的创建、静态及动态调用
转载:http://blog.csdn.net/welcome000yy/article/details/7905463 结合这篇博客:http://www.cnblogs.com/xumenger/ ...
- RT-Thread创建静态、动态线程
RT-Thread 实时操作系统核心是一个高效的硬实时核心,它具备非常优异的实时性.稳定性.可剪裁性,当进行最小配置时,内核体积可以到 3k ROM 占用. 1k RAM 占用. RT-Thread ...
- Delphi DLL文件的静态调用
- delphi dll创建及调用
第一章 DLL简单介绍由于在目前的学习工作中,需要用到DLL文件,就学习了下,在这里作个总结.首先装简单介绍下DLL:1,减小可执行文件的大小DLL技术的产生有很大一部分原因是为了减小可执行文件的大小 ...
- Delphi 类库(DLL)动态调用与静态调用示例讲解
在Delphi或者其它程序中我们经常需要调用别人写好的DLL类库,下面直接上示例代码演示如何进行动态和静态的调用方法: { ************************************** ...
- C++调用DLL有两种方法——静态调用和动态调用
C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报 分类: cpp(30) [ ...
- linux静态与动态库创建及使用实例
一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...
- dll静态调用和动态调用
动态链接库有2种连接方式,一种是通过库直接加入(又叫隐式加载或载入时加载),一种是在运行时加入.后者很好理解,比如LoadLibrary(),GetProcAddress()获取想要引入的函数,使用完 ...
- Delphi动态调用C++写的DLL
c++ DLL 文件,建议用最简单的c++编辑工具.不会加入很多无关的DLL文件.本人用codeblocks+mingw.不像 VS2010,DLL编译成功,调用的时候会提示缺其他DLL. 系统生成的 ...
随机推荐
- Centos6安装破解Confluence6.3.1
confluence是一个专业的企业知识管理与协同软件,可以用于构建企业wiki.通过它可以实现团队成员之间的协作和知识共享 安装和破解包百度网盘地址: 链接:https://pan.baidu.co ...
- 【CSS】text-align:justify 的使用
工作需要写一个全是文本的网页,规范格式的时候发现很多css属性不是很熟悉,比如text-align:justify. 这个是两端对齐,css3中新增了text-justify属性 语法:text-ju ...
- 【Luogu】【关卡2-13】线性数据结构(2017年10月)【还差一道题】
任务说明:数组,链表,队列,栈,都是线性结构.巧用这些结构可以做出不少方便的事情. P1996 约瑟夫问题 n个人,排成环形,喊到m的人出列,输出出列顺序. 咳咳,这个题目不好写,尽管简单就是模拟题. ...
- printf函数与缓冲区
printf函数与缓冲区 printf函数是一个行缓冲函数,先将内容写到缓冲区,满足一定条件后,才会将内容写入对应的文件或流中. 基本条件如下: .缓冲区填满 .写入的字符中有‘\n’ '\r' .调 ...
- Java的HashMap和Hashtable有什么区别HashSet和HashMap有什么区别?使用这些结构保存的数需要重载的方法是哪些?
HashMap与Hashtable实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用 两者的主要区别如下 1.Hashtable是早期JDK提供的接口,HashMap是新版J ...
- Fabric.js的使用
最近项目有一个绘制的功能,搜了一圈发现fabric.js口碑不错,但是文档稀缺,于是东看看西搜搜的把项目的需求都给实现了,想分享一下. 篇幅有点长,但看完后可以轻松驾驭fabric.我的项目是基于VU ...
- Tomcat免安装版踩坑
下载解压 从官网下载Tomcat的压缩包解压到硬盘上(这里用的是toncat7),解压之后目录如下(Windows) bin 存放tomcat的一些命令脚本 conf 存放配置文件 lib 存放运行时 ...
- pc端与移动端适配解决方案之rem
使用方式: 在html页面开头,引入下面的原生js代码 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'ori ...
- excrt——cf687b
excrt的理解 问对于方程组x = ai % ci 的 通解 x+tM, (x+tM) % k 是否有唯一值 看tm%k是否==0即可 #include<cstdio> #include ...
- C语言新手写扫雷攻略2
接下来是游戏的功能设计,要有扫雷的基本功能,左键点击雷区,右键红旗标记,并且可以统计雷数,可以重新开始,以下是游戏的功能初始 void Game(void) { while (1) { if (FLA ...