unit TestDll;interfaceuses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;type
  TForm1 = class(TForm)
    Label1: TLabel;
    Edit1: TEdit;
    Label2: TLabel;
    Edit2: TEdit;
    ComboBox1: TComboBox;
    Label3: TLabel;
    Edit3: TEdit;
    Label4: TLabel;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  TMultiplyNum=procedure;
var
  Form1: TForm1;
  MultiplyNum:TMultiplyNum;
  theHandle:THandle;implementation
function PlusNum(a,b:integer):integer;stdcall;external 'dll1\project1.dll';
function MinusNum(a,b:integer):integer;stdcall;external 'dll1\project1.dll';
//function MultiplyNum(a,b:integer):integer;stdcall;external 'dll2\project1.dll';
{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
begin
  case ComboBox1.ItemIndex of
  0: Edit3.Text :=IntToStr(PlusNum(StrToInt(Edit1.text),StrToInt(Edit2.text)));
  1: Edit3.Text :=IntToStr(MinusNum(StrToInt(Edit1.text),StrToInt(Edit2.text)));
  2: //Edit3.Text :=IntToStr(MultiplyNum(StrToInt(Edit1.text),StrToInt(Edit2.text)));
  begin
    theHandle :=LoadLibrary('E:\test\testDll\dll2\project1.dll');
    if theHandle<>0 then
    begin
      @MultiplyNum:=GetProcAddress(theHandle,'MultiplyNum');
      if @MultiplyNum<>nil then
      begin
        TMultiplyNum(MultiplyNum);
        FreeLibrary(theHandle);
      end;
    end;
  end;
  end;
end;
end.问题1:调用MultiplyNum函数的时候,调试状态下,在FreeLibrary(theHandle)后报地址冲突的错误,直接运行则自动退出程序
问题2:TMultiplyNum(MultiplyNum);这句话应该怎么理解,如果直接换成MultiplyNum;好像效果是一样的。

解决方案 »

  1.   

    if @MultiplyNum<>nil then
          begin
            TMultiplyNum(MultiplyNum);
            FreeLibrary(theHandle);
          end;
    改为
    if @MultiplyNum<>nil then
          begin
            MultiplyNum(参数);
          end;
        FreeLibrary(theHandle);
      

  2.   

    tomboy0(小波波) 
    应该不是这个原因,这个函数是调用一个MessageBox,用不到传入的参数,如果我不用动态装载的方式,而是象PlusNum,MinusNum那样直接调用是没有问题的。
      

  3.   

    unit TestDll;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Label1: TLabel;
        Edit1: TEdit;
        Label2: TLabel;
        Edit2: TEdit;
        ComboBox1: TComboBox;
        Label3: TLabel;
        Edit3: TEdit;
        Label4: TLabel;
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
      TMultiplyNum=function(a,b:integer):integer;stdcall;
    var
      Form1: TForm1;
      MultiplyNum:TMultiplyNum;
      theHandle:THandle;implementation
    function PlusNum(a,b:integer):integer;stdcall;external 'dll1\project1.dll';
    function MinusNum(a,b:integer):integer;stdcall;external 'dll1\project1.dll';
    //function MultiplyNum(a,b:integer):integer;stdcall;external 'dll2\project1.dll';
    {$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
    begin
      case ComboBox1.ItemIndex of
      0: Edit3.Text :=IntToStr(PlusNum(StrToInt(Edit1.text),StrToInt(Edit2.text)));
      1: Edit3.Text :=IntToStr(MinusNum(StrToInt(Edit1.text),StrToInt(Edit2.text)));
      2: //Edit3.Text :=IntToStr(MultiplyNum(StrToInt(Edit1.text),StrToInt(Edit2.text)));
      begin
        theHandle :=LoadLibrary('E:\test\testDll\dll2\project1.dll');
        if theHandle<>0 then
        begin
          @MultiplyNum:=GetProcAddress(theHandle,'MultiplyNum');
          if @MultiplyNum<>nil then
          begin
            TMultiplyNum(MultiplyNum);
            FreeLibrary(theHandle);
          end;
        end;
      end;
      end;
    end;
    end.