用Delphi编写使用到ADO的DLL的一些问题

作者:Sender Su  来源:原创内容  发布日期:2009-07-22  最后修改日期:2009-09-25

最近在把本人做的一个软件中的一些代码独立出来成为DLL模块供系统的其他组件调用。这些代码的最大特点是会在单元的Initialization中创建全局的静态对象,这些对象是数据库操作的封装,并在Finalization中释放。通过FastMM作为内存管理器并调整FastMM的参数,可以方便地直接使用Delphi的动态字符串进行参数传递。经过一轮鼓捣后,总结了一些问题如下:

1、FastMM要打开ShareMem的相关几个选项,可以修改INC文件实现;

2、需要向DLL传递Application.Handle,并在Dll中把接收到的值赋给DLL自己的Application.Handle。否则DLL中的窗体会接收不到键盘热键或者丢失某些消息;

3、DLL中的窗体不能设置默认最大化,需要在创建窗体后WindowState := wsMaximized这样来最大化,否则最大化后的窗口位置不对;

4、如果使用了ADO,由于ADO组件使用了COM接口,需要CoInitialize初始化。但是Delphi在COM的初始化中特意检查了当前程序是否DLL,如果是则跳过CoInitialize。很多人认为这个是Delphi的错误,但实际上这个是Microsoft的要求(可以在MSDN中查函数CoInitialize或CoUninitialize,有专门的说明)。就此来看,貌似只要在涉及到ADO的单元中加上CoInitialize和CoUninitialize便可。但是,由于Microsoft特意指出的,无法控制初始化/释放的顺序,结果会导致在Initialization中创建,在Finalization中释放的ADO对象在释放时可能由于已经CoUnitiialize而释放出错。解决办法只有:1)、所有ADO相关的对象都不能在Initialization/Finalization中处理;2)、使用动态加载的DLL 而不是静态加载,此时需要在主程序加载DLL前先执行CoInitialize。

5、进一步的试验发现,静态加载并设置了共享MemoryManager的DLL会导致FastMM在退出时的内存泄露报告功能消失,原因不明。因此,所有用到FastMM的DLL都应该动态加载。

最后贴一段我的DLL初始化代码:

var
  OldDllProc: TDLLProc;

procedure ThisDllProc(Reason: Integer);
begin
  if Reason = DLL_THREAD_ATTACH then
    IsMultiThread := True; // for FastMM

  // for ADO
  case Reason of
    DLL_PROCESS_ATTACH,
    DLL_THREAD_ATTACH:CoInitialize(nil);

    DLL_PROCESS_DETACH,
    DLL_THREAD_DETACH:CoUninitialize;
  end;

  if Assigned(OldDllProc) then
    OldDllProc(Reason);
end;

begin
  OldDllProc := DllProc;
  DllProc := ThisDllProc;
  ThisDllProc(DLL_PROCESS_ATTACH);
end.

 

本栏目相关
  •  2010-11-04 解决MySQL Cluster 备份总是失败,提示文件已存在的问题
  •  2010-03-15 MegaCli安装及使用杂记
  •  2010-09-24 解决WSUS显示客户端不全的问题
  •  2010-01-25 Linux 下的分区调整工具GParted实战
  •  2009-11-11 解决很好用的多合一即时通信软件pidgin的崩溃问题
  •  2009-09-25 解决Squid代理HTTP时在浏览器出现Content Encoding Error问题
  •  2009-07-22 用Delphi编写使用到ADO的DLL的一些问题
  •  2009-11-06 索尼系列手提电脑备份失败,出现700错误的解决办法
  •  2009-04-04 Dell R900服务器 BMC firmware incompatible with CPU 错误修正方法
  • 本站微信订阅号:

    微信订阅号二维码

    本页网址二维码:

    本栏目热门内容
  • Acrobat虚拟PDF打印机执行打印时挂起,解决办法竟然...
  • LINKSYS交换机登录WEB界面显示不正确的解决方法
  • 又一次RAID 5阵列故障记录
  • 解决VMware vSphere ESXi 5.0 Update 1 中虚机不能...
  • 修改CentOS发行信息以绕过Dell服务器BIOS更新和DSET...
  • 解决虚拟化运行的 Windows Server 2003 标准版出现...
  • Windows Server 2008 重命名域和域控制器
  • Intel Nehalem CPU Errata 导致 VMWare ESXi(vSpher...
  • 一次很精神的电脑组装过程记录(但不是自己的电脑)...
  • 解决MySQL Cluster 备份总是失败,提示文件已存在的...
  • MegaCli安装及使用杂记
  • 解决WSUS显示客户端不全的问题
  • 解决 VMWare vSphere 6 客户端无法修改用户密码
  • 解决Windows Server 2008 R2域控制器显示无法连接到...
  • 本站服务器RAID 5阵列双硬盘失效挽救记录
  • 网站数据库从MySQL 5.0升级到5.6的记录
  • 解决MariaDB使用Percona XtraBackup增量备份出错
  • DELL PowerEdge 820 报CPU3 INTERNAL ERROR 的解决...
  • Linux 下的分区调整工具GParted实战
  • 修改arpwatch使通知邮件主题显示IP地址
  • 程序员漫画:如何用8种不同的编程语言去解救公主
  • 解决Samba WINS服务的错误解释问题
  • 解决很好用的多合一即时通信软件pidgin的崩溃问题
  • 使用 GParted 进行虚拟机硬盘分区调整操作
  • 解决Squid代理HTTP时在浏览器出现Content Encoding ...
  • 用Delphi编写使用到ADO的DLL的一些问题
  • 网站简单改版
  • 索尼系列手提电脑备份失败,出现700错误的解决办法
  • Dell R900服务器 BMC firmware incompatible with C...
  • 更多...