我下面这些代码是调用一个dll中的窗体,静态调用没问题,用动态调用方式发现一个问题,可以调出窗体,但当DLL中调用出来的窗体关闭时,提示地址错误,请教一下是什么原因?
代码如下:
unit Unit1;         //dll的窗体单元文件interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls;
 function showmyform:boolean;stdcall;
type
  TForm1 = class(TForm)
 
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}
function showmyform:boolean;stdcall;
begin
  try
    form1:=Tform1.Create(application);
    result:=true;
    form1.ShowModal ;
    form1.Free ;
  except
    result:=false;
  end;
end;end.
library Project2; uses
  SysUtils,
  Classes,
  forms,
  unit1 in 'unit1.pas'{form1};
{$R *.res}
 exports
  showmyform;
begin
end.
//////下面是动态调用dll程序代码
unit Unit12;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  Tshowmyform=procedure(AHandle:THandle);stdcall;  TForm1 = class(TForm)
    Button1: TButton;
    CheckBox1: TCheckBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var libhandle:THandle;
    showmyform:Tshowmyform;
begin
if self.CheckBox1.Checked then
begin
   libhandle:=LoadLibrary('Project2.dll');
   try
    if libhandle<>0 then
      @showmyform:=GetProcAddress(libhandle,'showmyform');
      if @showmyform<>nil then
        showmyform(Application.Handle );
    finally
      FreeLibrary(libhandle);
    end;
end;
end;end.

解决方案 »

  1.   

    unit Unit1;        //dll的窗体单元文件 interface uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, Menus, StdCtrls; 
    function showmyform:boolean;//stdcall; 动态加载的要去掉
    type 
      TForm1 = class(TForm)   private 
        { Private declarations } 
      public 
        { Public declarations } 
      end; var 
      Form1: TForm1; implementation {$R *.dfm} 
    function showmyform:boolean;//stdcall; 实现部分不用stdcall
    begin 
      try 
        form1:=Tform1.Create(application); 
        result:=true; 
        form1.ShowModal ; 
        form1.Free ; 
      except 
        result:=false; 
      end; 
    end; end. 
    library Project2; uses 
      SysUtils, 
      Classes, 
      forms, 
      unit1 in 'unit1.pas'{form1}; 
    {$R *.res} 
    exports 
      showmyform; 
    begin 
    end. 
    //////下面是动态调用dll程序代码 
    unit Unit12; interface uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls; type 
      Tshowmyform=procedure(AHandle:THandle);//stdcall; 动态加载的要去掉  TForm1 = class(TForm) 
        Button1: TButton; 
        CheckBox1: TCheckBox; 
        procedure Button1Click(Sender: TObject); 
      private 
        { Private declarations } 
      public 
        { Public declarations } 
      end; var 
      Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); 
    var libhandle:THandle; 
        showmyform:Tshowmyform; 
    begin 
    if self.CheckBox1.Checked then 
    begin 
      libhandle:=LoadLibrary('Project2.dll'); 
      try 
        if libhandle <>0 then 
          @showmyform:=GetProcAddress(libhandle,'showmyform'); 
          if @showmyform <>nil then 
            showmyform(Application.Handle ); 
        finally 
          FreeLibrary(libhandle); 
        end; 
    end; 
    end; end.
      

  2.   

    showmyform 应该多写个参数条件进去,把调用者的句柄传递进去