(1)正确认识dll
Dll本质上一个独立的应用程序,与exe一样,有自己的地址空间。 因此,dll是一个可装载执行的程序。其他的,不多说了吧。
(2)调用DLL的方法
我用过的有三种。
第一种:用API
因为Delphi支持几乎所有的API,你可以在Delphi中直接调用API装载一个外部DLL。但是我不喜欢这样做,因为我讨厌微软的那套路。
第二种:外部函数引用
做一个单元(unit),引用外部函数。例如:
function myDllCall(var i:integer): Integer; stdcall; external 'mydll.dll' name 'mydllpro';
依赖于DLL接口输出方式,或者写成:
function myDllCall(var i:integer): Integer; stdcall; external 'mydll.dll' index my_index;
注意:stdcall,cdecl,safecall遵循从右至左的参数调用规则;register,pascal遵循从左至右的参数调用规则。但是cdecl释放参数的时机与其他几种方式还不一样。建议大家采用stdcall调用,因为无论是Delphi还是C,都可用。
第三种:推荐方式---地址引用
如果在Delphi中调用由Delphi生成的Dll,这种方式最好。
你可以把Dll名称与其输出调用接口作为参数传入,写一个通用的过程或者函数,调用所有的dll.
这是我的一个例子:
procedure tcommon_base.run_dlls_parameter(filename,modulename:string;
var parameter:tmy_object);
//dll中要使用对象parameter;并且可能对parameter作修改,必须返回修改。
var
handle:thandle;
p :procedure(var parameter:tobject);
a,b :array[0..255]of char;
begin
filename:='.\runtime\'+filename; //dll的路径和名字:自己定义。
strpcopy(a,filename); //转换为Pchar.
handle:=loadlibrary(a); //装入dll.并返回句柄。
if handle<>0 then //装入成功
begin
strpcopy(a,modulename); //转换调用接口为pchar.
@p:=getprocaddress(handle,a);//得到调用接口的进程地址。
if @p<>nil then
p(parameter) //调用Dll.含参数。
else
begin
strpcopy(b,'Method Not Defined: '+modulename+'!');
messagebox(message_parameter.mainhandle,b,
'Error...',mb_ok or mb_iconexclamation);
end;
end
else
begin
strpcopy(b,'Component Not Found: '+filename+'!');
messagebox(message_parameter.mainhandle,
b,'Error...',mb_ok or mb_iconexclamation);
end;
end;
说明:如果你有一个dll是这么写的,
library cancel_service;
uses
sharemem,
SysUtils,
Classes,
forms,
process_cancel_service,//你的dll应用模块,一个窗体。
my_global;
(******************************)
procedure run_cancel_service(var param:tmy_object);
begin
my_global.global_parameter:=param;
//把传入的参数对象地址赋给dll的同一个参数类.
//使得主程序的参数对象和dll中的参数对象指向同一个实例空间.
//这样,在process_cancel_service窗体中就可以
//通过my_global.global_parameter来访问主程序的组件了.
//因为他们指向同一个地址.
process_cancel_service_form:=tprocess_cancel_service_form.create(nil);
process_cancel_service_form.showmodal;
process_cancel_service_form.free;
end;
(******************************)
exports
run_cancel_service;
begin
end.
那么,调用方式:
run_dlls_parameter('cancel_service.dll',
'run_cancel_service',myglobal.global_parameter);
注意:global_parameter对象定义在my_global.pas中,它定义了一个公用的对象Tglobal_parameter,用来传递参数.这个unit在你的主程序和dll中都要用到.从逻辑上讲,这是两个完全独立的unit,只不过他们的结构和内容完全一样.因此只要在主程序中初始化这个实例,dll中就可以通过对象地址直接引用了.切莫在dll中再次初始化这个实例,那样就浪费空间了,会形成内存泄露.
(3)是不是看不懂呢? 继续听我讲.
调用dll很简单,问题是如何与dll传递参数?比如,我要与dll共享数据库组件,我要在主程序中打开一个表,然后在dll中操作这个表,怎么办?
其实很简单,我们可以分别在主程序和dll中定义一个相同的对象或者结构(记录类型):global_parameter,这个对象或者结构中包含了我们需要共享或者传递的参数,包括数据库连接组件等等.
但是,我们知道,exe和dll完全是两个进程,他们之间如何传递这些参数呢? 很简单,我们可以在主程序中把这个参数对象生成好了,然后把这个对象的地址作为参数传给dll, 使得他们访问同一个空间,不就可以了么?
事实上,前面的例子就是这么做的.他们之间传递了一个tmy_object类型的对象,因为对象的传递过程,本身就是对象地址的传递,而不是空间的克隆.所以,他们之间就共享了同一个对象,可以直接访问对象中的其他组件......并且在dll中对参数对象的任何修改,对于主程序都是可见的.

转载于:https://www.cnblogs.com/xiaobao/archive/2010/08/27/1810103.html

Delphi下DLL调用以及共享数据库连接相关推荐

  1. iSpy结合yolo复杂环境下DLL调用路径攻略

    前阵子接手了一个项目,客户是一个工厂,比较重视安全生产,整个厂区和车间安装了200多个摄像头,用的是海康的网络摄像头+硬盘存储服务器.目的是为了监控在生产车间生产人员是否正确配戴安全帽,是否有人吸烟, ...

  2. delphi XE 10实现App和PC下TreeView调用ImageList和Sqlite数据

    delphi XE 10实现App和PC下TreeView调用ImageList和Sqlite数据 一.工程 program TreeView; usesSystem.StartUpCopy,FMX. ...

  3. Windows 下 JNI 调用动态链接库 dll

    1. Java调用本地代码常见的两种方案 JNI JNI(Java Native Interface),有过不同语言间通信开发经历的一般都知道,它允许java和其他语言代码(尤其是C/C++)进行交互 ...

  4. Delphi中动态调用DLL的方法

    Delphi中动态调用dll的方法如下: function CallFunc(dllname, funcname: string; const param: array of const): DWOR ...

  5. Delphi下的COM编程

    Delphi通过向导可以非常迅速和方便的直接建立实现COM对象的代码,但是整个COM实现的过程被完全的封装,甚至没有VCL那么结构清晰可见. 一个没有C++下COM开发经验甚至没有接触过COM开发的D ...

  6. MFC下DLL编程(图解)

    DLL(Dynamic Link Library,动态链接库)是微软公司为Windows和OS/2操作系统设计一种供应用程序在运行时调用的共享函数库.DLL是应用程序的一种扩展,也是软件共享和重用的传 ...

  7. 如何查看exe或dll调用了什么dll

    [转载]如何查看exe或dll调用了什么dll呢 已有 19410 次阅读 2014-4-17 21:08|系统分类:科研笔记|文章来源:转载 Dependency Walker使用说明 在Windo ...

  8. Delphi与C++Builder代码共享的实现

    原文地址: http://blog.chinaunix.net/uid-16175364-id-2752232.html Delphi与C++Builder代码共享的实现 2006-10-30 13: ...

  9. Delphi下利用WinIo模拟鼠标键盘详解

    本文最早在编程论坛上发表,文章地址:http://programbbs.com/bbs/view12-17207-1.htm,相关文件可以在上述地址的页面中下载.转载时请注明出处. 前言 一日发现Se ...

最新文章

  1. SQL Server数据库错误9003(LSN无效)的处理方法
  2. 施耐德电气:2016年数据中心的三大关注领域
  3. 使用Spring boot,Thymeleaf,AngularJS从零开始构建一个新的Web应用程序-第3部分
  4. html网页主题结构,常用html元素总结包括基本结构、文档类型、头部、主体等等...
  5. ios两个app之间传值和跳转实现(转发)
  6. 容器中运行Fabric区块链网络
  7. IOS 获取.plist文件的数据
  8. java制作大富翁游戏_JAVA大富翁游戏的设计+流程图+总结体设计图-论文.doc
  9. xise菜刀千万不要随便下载!(警惕!)
  10. _stdcall相关
  11. ArchLinux安装错误”Errors occured, no packages were upgraded. ⇒ ERROR: Failed to install packages to new“
  12. matlab的from模块_Matlab中SIMULINK的模块库以及比较常用的模块
  13. App启动页倒计时圆形并且跳过功能实现
  14. Kotlin 只读变量
  15. 单片机list文件解析及 hardfalt问题定位
  16. Android解析服务器Json数据实例
  17. 苹果cms播放器不能全屏播放解决方法
  18. 为什么打开CAD显示驱动该文件(.hdi)缺少或已损坏?
  19. Inner Join与Left Join
  20. c语言程序设计(西安理工大学),C语言程序设计-西安理工大学三电实验教学中心!.doc...

热门文章

  1. 华为(英国)招聘CPU/GPU架构及系统软件工程师
  2. 商汤春招特别策划-春招百晓生系列空宣第2期,助你收获心动的offer
  3. 20种小技巧,玩转Google Colab
  4. 12分钟训练COCO模型!速度精度双提高
  5. Python学习:快速搭建python环境
  6. python也能写emoji表情?两个函数解决两者之间的联系
  7. 图机器学习有多大神力?一文带你回顾2020,展望2021
  8. 上海纽约大学发布2019届毕业生就业报告,出国深造比高达67%
  9. 大数据分析必须要会的python函数操作!!!
  10. java数组写99乘法表,Java 实现乘法口诀(99乘法表)