根据Delphi提供的有关 DLL编写和调用的帮助信息,你可以很快完成一般的 DLL编写和调用的 应用程序。本文介绍的主题是如何编写和调用能够传递各种参数(包括对象实例)的 DLL。例如, 主叫程序传递给 DLL一个ADOConnection 对象示例作为参数, DLL中的函数和过程调用通过该对象实例访问数据库。
需要明确一些基本概念。对于 DLL,需要在主程序中包含 exports子句,用于向外界提供调用 接口,子句中就是一系列函数或过程的名字。对于主叫方(调用 DLL的应用程序或其它的 DLL), 则需要在调用之前进行外部声明,即external保留字指示的声明。这些是编写 DLL和调用 DLL必须 具备的要素。
另外需要了解Object Pascal 中有关调用协议的内容。在Object Pascal 中,对于过程和函数 有以下五种调用协议:

指示字 参数传递顺序 参数清除者 参数是否使用寄存器
register 自左向右 被调例程
pascal 自左向右 被调例程
cdecl 自右向左 调用者
stdcall 自右向左 被调例程
safecall 自右向左 被调例程
这里的指示字就是在声明函数或过程时附加在例程标题之后的保留字,默认为register,即是 唯一使用 CPU寄存器的参数传递方式,也是传递速度最快的方式;

  • pascal: 调用协议仅用于向后兼容,即向旧的版本兼容;
  • cdecl: 多用于 C和 C++语言编写的例程,也用于需要由调用者清除参数的例程;
  • stdcall: 和safecall主要用于调用Windows API 函数;其中safecall还用于双重接口。

在本例中,将使用调用协议cdecl ,因为被调用的 DLL中,使用的数据库连接是由主叫方传递 得到的,并且需要由主叫方处理连接的关闭和销毁。

下面是 DLL完整源程序和主叫程序完整源程序。包括以下四个文件:
Project1.DPR {主叫程序}
Unit1.PAS {主叫程序单元}
Project2.DPR {DLL}
Unit2.PAS {DLL单元}

{---------- DLL 主程序 Project2.DPR ----------}

library Project2;

uses
SysUtils,
Classes,
Unit2 in 'Unit2.pas' {Form1};

{$R *.RES}

{ 下面的语句用于向调用该 DLL的程序提供调用接口 }
exports
DoTest; { 过程来自单元Unit2 }

begin
end.

{---------- DLL中的单元 Unit2.PAS ----------}

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, ADODB, StdCtrls, Menus;

type
TForm1 = class(Tform)
ADOConnection1: TADOConnection;{ 本地数据库连接 }
Memo1: Tmemo; { 用于显示信息 }
private
public
end;

{ 该过程向外提供 }
procedure DoTest(H: Thandle; { 获得调用者的句柄 }
Aconn: TADOConnection;{ 获得调用者的数据库连接 }
S: string; { 获得一些文本信息 }
N: Integer); { 获得一些数值信息 }
cdecl; { 指定调用协议 }

implementation

{$R *.DFM}

procedure DoTest(H: Thandle; Aconn: TADOConnection; S: string; N: Integer);
begin
Application.Handle := H; { 将过程的句柄赋值为调用者的句柄 }
{ 上面语句的作用在于, DLL的句柄和调用者的句柄相同,在任务栏中就不会 }
{ 各自出现一个任务标题了。 }
with TForm1.Create(Application) do try{ 创建窗体 }
Memo1.Lines.Append('成功调用'); { 显示一行信息 }
ADOConnection1 := Aconn; { 获得数据库连接的实例 }
Memo1.Lines.Append(
ADOConnection1.ConnectionString +
' - ' + S + ' - ' + IntToStr(N)); { 根据得到的参数显示另一行信息 }
ShowModal; { 模式化显示窗体 }
finally
Free; { 调用结束时销毁窗口 }
end;
end;

end.

{---------- 调用者 Project1.DPR,很普通的工程文件 ----------}

program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

{---------- 调用者单元Unit1.PAS ----------}

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, ADODB;

type
TForm1 = class(Tform)
Button1: Tbutton; { 按此按钮进行调用 }
ADOConnection1: TADOConnection; { 本地数据库连接,将传递给 DLL }
procedure Button1Click(Sender: Tobject);{ 调用 DLL}
private
public
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{ 外部声明必须和 DLL中的参数列表一致,否则会运行时错误 }
procedure DoTest(H: Thandle; { 传递句柄 }
Aconn: TADOConnection; { 传递数据库连接 }
S: string; { 传递文本信息 }
N: Integer); { 传递数值信息 }
cdecl; { 指定调用协议 }
external 'Project2.dll';{ 指定过程来源 }

{ 调用过程 }
procedure TForm1.Button1Click(Sender: Tobject);
begin
DoTest(Application.Handle,
ADOConnection1,
'Call OK',
256);
end;

end.
 

Delphi中高级DLL的编写和调用相关推荐

  1. C++笔记-DLL的编写与调用

    目录 基本概念 代码与实例 基本概念 Visual Studio的编译环境下,DLL分为3类: 非MFC的DLL,使用SDK API进行编程,能被所有语言调用. MFC规则DLL,可以使用MFC进行编 ...

  2. 动态库的编写和调用 - Delphi

    uDll.pas   function Add10(ANum: integer): integer; stdcall; //Delphi 默认采用 register 调用约定,如果dll涉及跨语言调用 ...

  3. Delphi下DLL调用以及共享数据库连接

    (1)正确认识dll Dll本质上一个独立的应用程序,与exe一样,有自己的地址空间. 因此,dll是一个可装载执行的程序.其他的,不多说了吧. (2)调用DLL的方法 我用过的有三种. 第一种:用A ...

  4. jni 从c传递map到java_java_jni 本地调用接口DLL的编写样本,涉及数组传递,相关的 和C程序均已包括。 Develop 256万源代码下载- www.pudn.com...

    文件名称: java_jni下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 8055 KB 上传时间: 2016-04-16 下载次数: 0 提 供 者: 普云 ...

  5. 视频教程-PHP扩展模块开发之DLL编写与调用-PHP

    PHP扩展模块开发之DLL编写与调用 云知梦创始人,国际架构师,11年互联网培训和开发经验,曾在港电讯盈科.北大青鸟集团.远大教育.北京易第优教育等公司任职曾获得美国红帽RHCA构架师和RHCDS数据 ...

  6. DLL的生成、编写、调用总结

    一. DLL的创建 1. 创建环境 VS2022(注:其他VS大同小异) 2. 创建过程 新建My_Dll项目 点击确定 ->下一步->输入DLL工程的名称My_Dll->创建. 3 ...

  7. Delphi中DLL封装业务逻辑的实现

      三层结构是开发C/S或B/S系统经常采用的策略,这种分层方式将系统分为用户服务.业务服务和数据服务三部分,能够解决客户端与服务器结构维护成本问题.改善客户端与服务器结构延展性问题:解决应用逻辑重复 ...

  8. c++创建包含opencv的dll供C,C#调用

    最近做项目,需要将C++算法封装成dll,给C#调用,之前没接触过C#,现学一波,只做了dll并用C#测试了下,运行成功.记录下来过程,供大家参考. 编程环境:VS2013+opencv2.4.13 ...

  9. 动态链接库的编写与调用

    动态链接库是编绎好的二进制文件与exe文件类似,但它不能单独运行.它是一个独立的模块,也包含了代码.数据或资源,能被其它程序共享.多个程序调用动态链接库里的同一个函数时,理论上该函数在内存中只存在一份 ...

最新文章

  1. 第五期直播《聊聊目标检测和秋招那些事》精彩回顾
  2. spring mvc DispatcherServlet详解之前传---FrameworkServlet
  3. 【MFC】工具栏按钮多选效果本
  4. std::ios::sync_with_stdio(false)的运用
  5. ListBox类似组件,鼠标右键点击事件得到选中Item
  6. Codeforces Round #277 (Div. 2) A. Calculating Function 水题
  7. php发送163邮件554,PHPMailer配置163邮箱发送邮件
  8. dsp呼吸灯C语言编程,DSP28335 呼吸灯程序
  9. 2017 JavaScript生态圈调查报告
  10. mysql 查看内核版本命令_Linux查看版本命令问题
  11. 拓端tecdat|R语言模拟和预测ARIMA模型、随机游走模型RW时间序列趋势可视化
  12. mysql 管理工具—phpmyadmin docker 版使用
  13. UCDOS作者---鲍岳桥
  14. 手机号微信检测方法案例分析
  15. matlab igbt 关断,IGBT关断过程的分析
  16. firefox新标签页背景_如何更改或自定义Firefox的“新标签页”
  17. 计步器 c语言,ADXL345单片机计步器程序
  18. STAT0023 STATISTICS FOR PRACTICAL COMPUTING
  19. Vue ui/vue create创建项目报错:Failed to get response from https://registry.npmjs.org/vue-cli-version-ma
  20. 微信「扫一扫识物」 的背后技术揭秘

热门文章

  1. Redis实现求交集操作结果缓存的设计方案
  2. tcp/udp socket编程异同
  3. 此情应是长相守 你若无心我便休
  4. NYOJ 721 纸牌游戏 简单题
  5. UNIX/Linux-进程控制(实例入门篇)
  6. 服务器意外重启导致storm报错的问题处理
  7. 70后、80后、90后的区别(很有意思)
  8. 电信系统方案 电信综合营帐系统
  9. 机器学习--CART分类回归树
  10. Linux 下从命令行打开pdf文件和html文件的命令