下面是我的代码,exe动态加载dll “baseinfo”,在dll的DLL_PROCESS_DETACH中写了卸载dll语句,实现dll封装的窗体关闭后就卸载dll,好节约内存,现在程序运行不报错,也没内存泄漏,就是当封装的MDI子窗体关闭后,dll不能自动卸载,还占据着内存,请教高手有什么办法能实现动态卸载dll,好节约内存。
library baseinfo;//dll的代码
uses
  SysUtils,
  Classes,
  ADODB,
  Windows,
  Forms,
  d_baseinfo in 'd_baseinfo.pas' {dfmBaseInfo};
var
  DllApp:TApplication;    //定义变量
{$R *.res}
procedure CallBaseinfo(const app:TApplication;const adocnn:Tadoconnection);stdcall;
begin
  Application:=app;
  if dfmBaseInfo=nil then
  begin
    dfmBaseInfo:=TdfmBaseInfo.Create(app);//创建mdi子窗体
    dfmBaseInfo.ADOConnection1:=adocnn;  //把参数adocnn对象赋给ADOConnection1获得数据库连接
  end;
  dfmBaseInfo.Show;
end;
procedure MyDLLProc(Reason:Integer);
begin
  if Reason=DLL_PROCESS_DETACH then
  begin
    if Assigned(DllApp) then
      Application:=DllApp;
    FreeLibrary(Application.Handle);   //进程退出时卸载dll
  end;
end;
exports
  CallBaseinfo;
begin
  DllApp:=Application;    //把dll的Application先存起来
  DllProc:=@MyDLLProc;    //
end.//exe的调用代码
type
  PlugIn=function(const app:TApplication;const adocnn:Tadoconnection):integer;stdcall;
……procedure Tf_main.N3Click(Sender: TObject);
var
  ahandle:THandle;
  plug:PlugIn;
begin
  ahandle:=LoadLibrary('baseinfo.dll') ;   //动态加载DLL
  try
  if ahandle=0 then
    exit;
  @plug:=GetProcAddress(ahandle,'CallBaseinfo');
  if @plug<>nil then
  plug(Application,ADOConnection1);
  finally
    freelibrary(ahandle);
  end;
end;

解决方案 »

  1.   

    不好意思,调用的exe程序发错了,调用代码是:
    //exe的调用代码
    type
      PlugIn=function(const app:TApplication;const adocnn:Tadoconnection):integer;stdcall;
    ……procedure Tf_main.N3Click(Sender: TObject);
    var
      ahandle:THandle;
      plug:PlugIn;
    begin
      ahandle:=LoadLibrary('baseinfo.dll') ;  //动态加载DLL
      if ahandle=0 then
        exit;
      @plug:=GetProcAddress(ahandle,'CallBaseinfo');
      if @plug <>nil then
      plug(Application,ADOConnection1);
    end; 
      

  2.   

    看看另外一种调用方法http://download.csdn.net/source/788118
      

  3.   

    楼上给我的地址是静态调用,主程序启动时就启动了dll,还不如我的方法呢,更费内存。我想要的是动态调用并动态释放,动态调用时有办法,但是动态卸载还没找到方法
      

  4.   

    使用回调函数,主程序中定义一个释放动态库的函数,调用dll时将函数指针传递到dll里,当dll窗体关闭后,调用主程序中的函数关闭。
      

  5.   

    类似于如下,但是不完整,不能通过编译,通过了运行也会报错,只是提供思路用:
    主程序:
    procedure freelib(h:Thandle);
    begin
    FreeLibrary(h);  //这里需要到timer中去释放,不能直接释放,否则报错。
    end;procedure Tf_main.N3Click(Sender: TObject); 
    var 
      ahandle:THandle; 
      plug:PlugIn; 
    begin 
      ahandle:=LoadLibrary('baseinfo.dll') ;  
      try 
      if ahandle=0 then 
        exit; 
      @plug:=GetProcAddress(ahandle,'CallBaseinfo'); 
      if @plug <>nil then 
      plug(Application,ADOConnection1,@freelib); 
    end; 
    动态库:
    type
    TMyFreeLibrary=procedure(h:Thandle);
    .
    .
    .
    procedure Tform1.FormClose(Sender: TObject;
      var Action: TCloseAction);
    var
    freelib:TMyFreeLibrary;
    begin
    @freelib:=传递进来的指针;
    end;
      

  6.   

    类似于如下,但是不完整,不能通过编译,通过了运行也会报错,只是提供思路用:
    主程序:
    procedure freelib(h:Thandle);
    begin
    FreeLibrary(h);  //这里需要到timer中去释放,不能直接释放,否则报错。
    end;procedure Tf_main.N3Click(Sender: TObject); 
    var 
      ahandle:THandle; 
      plug:PlugIn; 
    begin 
      ahandle:=LoadLibrary('baseinfo.dll') ;  
      try 
      if ahandle=0 then 
        exit; 
      @plug:=GetProcAddress(ahandle,'CallBaseinfo'); 
      if @plug <>nil then 
      plug(Application,ADOConnection1,@freelib); 
    end; 
    动态库:
    type
    TMyFreeLibrary=procedure(h:Thandle);
    .
    .
    .
    procedure Tform1.FormClose(Sender: TObject;
      var Action: TCloseAction);
    var
    freelib:TMyFreeLibrary;
    begin
    @freelib:=传递进来的指针;
    end;
      

  7.   

    你可以看看dll的入口函数的另一种方法
    function OpenForm(mainForm:TForm):Longint;
    var 
      DLLForm: TDllForm;
      ptr:PLongInt;
    begin
      ptr:=@(Application.MainForm);
      ptr^:=LongInt(mainForm);
      DLLForm:= TDllForm.Create(mainForm);
      Result :=longInt(DLLForm);
      DLLForm.Show;
    end;
    里面还有一个控制释放的方法
    procedure FormFree(AFormRef: Longint);
    begin
      if AFormRef > 0 then
        TDLLForm(AFormRef).Release;
    end;
    通过调用窗体释放资源
    调用的时候用动态还是静态与入口函数没有关系的
      

  8.   

    都不是好办法,太麻烦,要是每个MDI子窗体都这么解决,就太麻烦了,看来delphi用dll封装mdi本身就是个麻烦,我还是考虑怎么用消息吧