[转]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. 系统生成的 ...
随机推荐
- transformer模型计算图
参考了这篇文章:http://nlp.seas.harvard.edu/2018/04/03/attention.html 结合代码和图,能更加清楚的了解transformer中的一些原理(ps,等下 ...
- 面试之加分项vue(没看懂,。。。。)
对大部分人来说,掌握Vue.js基本的几个API后就已经能够正常地开发前端网站.但如果你想更加高效地使用Vue来开发,成为Vue.js大师,那下面我要传授的这五招你一定得认真学习一下了.在面试过程很多 ...
- Eclipse如何设置jsp文件默认UTF-8格式编码
我使用的是Eclipse Jee Neon, Window->Preferences 具体设置如图所示:
- FromBase64String(String)和Encoding.Default.GetBytes(String)
今天突然被问FromBase64String(String)和Encoding.Default.GetBytes(String)有啥区别,我刚开始学C#对这个一脸懵逼,于是总结一下今天查资料的内容. ...
- QDomDocument::clear()的调用,会导致关闭程序时崩溃!!!
//读一份xml前,先清理m_Doc[QDomDocument] bool XmlIO::xmlRead(QString &errmsg) { m_mutex.lock(); // m_Doc ...
- 管理员技术(二): 访问练习用虚拟机、 命令行基础技巧 、 挂载并访问光盘设备、ls列表及文档创建、复制删除移动
一.访问练习用虚拟机 目标: 学会在教学环境中访问练习用虚拟机,主要完成以下事项: 1> 快速重置教学虚拟机环境 2> 通过“虚拟系统管理器”访问虚拟机 3> ...
- [Catalan数三连]网格&有趣的数列&树屋阶梯
如何让孩子爱上打表 Catalan数 Catalan数是组合数学中一个常出现在各种计数问题中的数列. 以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名. 先丢个公式(设第n项为$ ...
- 提高ASP.NET首页性能的方法
1.js压缩文件,css压缩文件,引用的越少越好. 2.用 HTTP Module 控制页面的生命周期. 3.自定义生成动态页面的静态内容 . 4.页面用GZIP压缩. 5.OutputCache 编 ...
- WinDbg中Check for invalid symbols or bad syntax(断点设置)解决办法
基础知识 bp 程序运行过程中下断点 bu 程序未加载之前下断点 bl 列出所有断点 bc 清除断点 今天在调试驱动的时候 发现下好断点后 无法调试 WinDbg显示 kd> g Break ...
- snmp相关网址
https://blog.csdn.net/wangcg123/article/details/53837737 https://www.linuxidc.com/Linux/2012-05/6114 ...