D2009 UP3和D2010 V3449 都没解决DLL的问题!(值得大家研究)

DLL的DPR代码如下:
library DllPro;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SimpleShareMem,
  SysUtils,
  Forms,
  Windows,
  Classes,
  uIntf in 'uIntf.pas',
  uImp in 'uImp.pas',
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

var
  DLLApp: TApplication;

function InitDLL(App: TApplication): Intf_DLLTest;
begin
  //问题出在这句上,
  //如果没有这句程序退出时就不会出错。
  //但是这句在DLL里一般都是要这样做的。否则DLL里的窗口显示的图标都是不正确的。
  //这样的代码在Delphi 2007以前是不会有问题的。
  Application := App;


  Obj_DLLTest := TImpl_DLLTest.Create(nil);

  Intf_DLLTest1 := Obj_DLLTest as Intf_DLLTest;
  Result := Intf_DLLTest1;
end;

procedure UnInitDLL;
begin
  FreeAndNil(Obj_DLLTest);
end;

procedure ExitDLL(Reason: Integer);
begin
  if Reason = DLL_PROCESS_DETACH then
  begin
    Application := DLLApp;
  end;
end;

exports
  InitDLL,
  UnInitDLL;

begin
  DLLApp := Application;
  DLLProc := @ExitDLL;


end.

调用DLL的主程序的主窗口的代码如下:

unit Main;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  uIntf;

var
  InitDLL: function (App: TApplication): Intf_DLLTest;
  UnInitDLL: procedure;

  DllHandle: THandle;

procedure TForm1.Button1Click(Sender: TObject);
begin
  DllHandle := LoadLibrary('DllPro.dll');
  if DllHandle > 0 then
  begin
    InitDLL := GetProcAddress(DllHandle, 'InitDLL');
    if Assigned(InitDLL) then
    begin
      Intf_DLLTest1 := InitDLL(Application);

      if Intf_DLLTest1 <> nil then
      begin
        Intf_DLLTest1.ShowTestForm;
      end;
    end;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if DllHandle > 0 then
  begin
    if Assigned(Intf_DLLTest1) then Intf_DLLTest1 := nil;

    UnInitDLL := GetProcAddress(DllHandle, 'UnInitDLL');
    if Assigned(UnInitDLL) then
    begin
      UnInitDLL;
    end;

    FreeLibrary(DllHandle);
  end;
end;

end.


详细原代码请看这里:

https://files.cnblogs.com/AnyDelphi/Dll_Intf.rar

#1楼 2009-08-15 14:38 | skaly
没有那样复杂,只要记着一点:外面传入的Application 要还给外面的程序释放,内部的Application在DLL释放的时候再自己释放就OK了,你这个错误是DLL内部和外面都在释放外面的Application引起的
#2楼 [楼主] 2009-08-25 17:11 | doorkey
楼上的搞错了。
我的程序在DLL里并没有释放传进来的 Application
 https://www.cnblogs.com/AnyDelphi/archive/2009/06/15/1503427.html
posted @   findumars  Views(612)  Comments(0Edit  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2016-01-13 感觉Release有时比Debug要健壮
2016-01-13 QTexstStream的操作对象是QIODevice(因此QFile,QBuffer,QProcess,QTcpSocket都可以使用),或者QString
2016-01-13 如何去掉IE控件的垂直滚动条(使用QAxWidget加载IE控件)
2016-01-13 由动态库文件dll生成lib库文件(手动生成.def文件,然后使用lib命令编译,非常牛),同理可使用dll生成.a库文件
2016-01-13 OpenBlas编译方法(体验msys下使用MingW)
2016-01-13 编写Qt Designer自定义控件(一)——如何创建并使用Qt自定义控件(一共4篇文章)
2016-01-13 限制QLineEdit的数值输入范围(一共4种限制器:QDoubleValidator, QIntValidator, QRegExpValidator, 和QRegularExpressionValidator)
点击右上角即可分享
微信分享提示