微信订阅号二维码

本页内容二维码:

本栏目热门内容
  • Acrobat虚拟PDF打印机执行...
  • LINKSYS交换机登录WEB界面...
  • 又一次RAID 5阵列故障记录...
  • 解决VMware vSphere ESXi ...
  • 修改CentOS发行信息以绕过...
  • Windows Server 2008 重命...
  • 解决虚拟化运行的 Windows...
  • Intel Nehalem CPU Errata...
  • 某卢瑟装机搞得一踏糊涂,...
  • 解决MySQL Cluster 备份总...
  • MegaCli安装及使用杂记
  • 解决WSUS显示客户端不全的...
  • 解决 VMWare vSphere 6 客...
  • 解决Windows Server 2008 ...
  • 本站服务器RAID 5阵列双硬...
  • 网站数据库从MySQL 5.0升...
  • 解决MariaDB使用Percona X...
  • 修改arpwatch使通知邮件主...
  • Linux 下的分区调整工具GP...
  • DELL PowerEdge 820 报CPU...
  • 程序员漫画:如何用8种不...
  • 解决很好用的多合一即时通...
  • 使用 GParted 进行虚拟机...
  • 解决Samba WINS服务的错误...
  • 解决Squid代理HTTP时在浏...
  • 用Delphi编写使用到ADO的D...
  • 网站简单改版
  • 索尼系列手提电脑备份失败...
  • Dell R900服务器 BMC firm...
  • 更多...

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

    作者:Sender  来源:WaveCN.com  发布日期: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 错误修正方法
  • 返回页首