`

回答一位朋友的提问:在Delphi7下如何与DLL共享数据库连接

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

朋友,你好!

因为有疑问,所以要思考;因为找不到答案,所以要询问。文明,就在疑惑与不懈的探索中演进。

我的一些文章赢得部分人的关注,我因此而荣幸。于是,QQ上朋友顿然多了起来。很多问题在QQ上无法简单的答复,还有一些问题是提问者自己也不知道如何表达,更谈不上解决问题了。

时间和精力对于我,太匮乏。我无法一次性回答所有的问题,这里权且回答一个“如何与dll共享数据库连接”的问题吧。非常抱歉,你的QQ号被我的太太删除了,她以为你是一位女士:)。

(1)正确认识dll

Dll本质上一个独立的应用程序,与exe一样,有自己的地址空间。因此,dll是一个可装载执行的程序。其他的,不多说了吧。

(2)调用DLL的方法

我用过的有三种。

第一种:用API

因为Delphi支持几乎所有的API,你可以在Delphi中直接调用API装载一个外部DLL。但是我不喜欢这样做,因为我讨厌微软的那套路。

第二种:外部函数引用

做一个单元(unit),引用外部函数。例如:

functionmyDllCall(vari:integer):Integer;stdcall;external'mydll.dll'name'mydllpro';
依赖于DLL接口输出方式,或者写成:
functionmyDllCall(vari:integer):Integer;stdcall;external'mydll.dll'indexmy_index;

注意:stdcall,cdecl,safecall遵循从右至左的参数调用规则;register,pascal遵循从左至右的参数调用规则。但是cdecl释放参数的时机与其他几种方式还不一样。建议大家采用stdcall调用,因为无论是Delphi还是C,都可用。

第三种:推荐方式---地址引用

如果在Delphi中调用由Delphi生成的Dll,这种方式最好。
你可以把Dll名称与其输出调用接口作为参数传入,写一个通用的过程或者函数,调用所有的dll.

这是我的一个例子:

proceduretcommon_base.run_dlls_parameter(filename,modulename:string;
varparameter:tmy_object);
//dll中要使用对象parameter;并且可能对parameter作修改,必须返回修改。
var
handle:thandle;
p:procedure(varparameter:tobject);
a,b:array[0..255]ofchar;
begin
filename:='./runtime/'+filename;//dll的路径和名字:自己定义。
strpcopy(a,filename);//转换为Pchar.
handle:=loadlibrary(a);//装入dll.并返回句柄。
ifhandle0then//装入成功
begin
strpcopy(a,modulename);//转换调用接口为pchar.
@p:=getprocaddress(handle,a);//得到调用接口的进程地址。
if@pnilthen
p(parameter)//调用Dll.含参数。
else
begin
strpcopy(b,'MethodNotDefined:'+modulename+'!');
messagebox(message_parameter.mainhandle,b,
'Error...',mb_okormb_iconexclamation);
end;
end
else
begin
strpcopy(b,'ComponentNotFound:'+filename+'!');
messagebox(message_parameter.mainhandle,
b,'Error...',mb_okormb_iconexclamation);
end;
end;

说明:如果你有一个dll是这么写的,
librarycancel_service;
uses
sharemem,
SysUtils,
Classes,
forms,
process_cancel_service,//你的dll应用模块,一个窗体。
my_global;

(******************************)
procedurerun_cancel_service(varparam: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中对参数对象的任何修改,对于主程序都是可见的.

中午没有休息,有点晕乎乎的感觉,可能没有表达清楚,请原谅!




分享到:
评论

相关推荐

    Delphi7 编程 100 实例

    ToolBar工具栏控件的使用 动态建立主菜单选项 窗口界面的动态分隔条...DLL中调用子窗口 新颖的资源管理器界面 如何生成半圆形窗口 制作字幕滚动窗体 详解Canvas生成渐变色窗口背景 WINAPM风格磁化...

    《Delphi7编程100例》代码

    《Delphi7编程100例》代码目录:---------------------------------------------ToolBar工具栏控件的使用动态建立主菜单选项窗口界面的动态分隔条动态设置选项卡页面在标题栏中自定义按钮窗体开合窗帘效果Windows XP...

    Delphi7编程100例

    在远程数据库中实现主从表关系 动态设置远程数据库的查询参数 在远程数据库中计算统计值 多线程与数据库 使用远程存储过程 数据模块的同步显示 建立Web服务的数据提供端 建立Web服务的数据访问端 ...

    Delphi5开发人员指南

    9.8.1 在16位Delphi中捕捉异常 250 9.8.2 异常和Safecall指示符 250 9.9 回调函数 250 9.9.1 使用回调函数 253 9.9.2 拥有者绘制的列表框 253 9.10 从DLL中调用回调函数 253 9.11 在不同的进程间共享DLL数据 256 ...

    Delphi编程100例

    在远程数据库中实现主从表关系 动态设置远程数据库的查询参数 在远程数据库中计算统计值 多线程与数据库 使用远程存储过程 数据模块的同步显示 建立Web服务的数据提供端 建立Web服务的数据访问端 开发WebSnap数据库...

    delphi7编程百例

    ToolBar工具栏控件的使用 动态建立主菜单选项 窗口界面的...DLL中调用子窗口 新颖的资源管理器界面 如何生成半圆形窗口 制作字幕滚动窗体 详解Canvas生成渐变色窗口背景 WINAPM风格...

    网管教程 从入门到精通软件篇.txt

    Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。 ...

    易语言程序免安装版下载

     静态编译后的易语言EXE/DLL之间不能再共享譬如窗口、窗口组件等类似资源,对于已经静态连接到一个EXE/DLL中的支持库,该支持库中的数据或资源将不能再被其它EXE/DLL中所使用的同名支持库访问。这是因为代码被分别...

    软件本地化工具 Sisulizer Enterprise Edition 4.0 Build 374 中文免费.zip

    Sisulizer Enterprise Edition 的第3版支持新的平台,如Android, FireMonkey, Delphi XE2 64位和改进。 NET支持。它配备了许多新的功能,如翻译记忆编辑器,真正的HTML预览,和几十个内置的更多有用的改进。建议所有...

Global site tag (gtag.js) - Google Analytics