type
   Tfunc = function (sParam:String): Boolean; stdcall;procedure TServerFuncMgr.CallBackFun();
var 
   CallFun: Tfunc;
   libHandle: THandle;
begin
  libHandle :=LoadLibrary(PChar('test.dll'));
  @CallFunc := GetProcAddress(libHandle, PChar('Max'));
  CallFunc('11');    
end;
按上面运行到CallFunc('11')可以正常调用dll中函数。
但现在我想先保存Max这个函数的地址,让此函数返回对应函数地址,在其他地方但调用一直报错,修改如下:
function TServerFuncMgr.CallBackFun():Tfunc
var 
   CallFun: Tfunc;
   libHandle: THandle;
begin
  libHandle :=LoadLibrary(PChar('test.dll'));
  @CallFunc := GetProcAddress(libHandle, PChar('Max'));
  Result := CallFunc;   
end;在另外的函数中调用
根据TServerFuncMgr.CallBackFun()的返回值CallFunc调用CallFunc('111')报错,请问是什么原因?如何修改?我就是想先得到dll中函数地址,保存起来,到适当时候调用,而不是一得到马上调用

解决方案 »

  1.   

    修改为如下试下:function TServerFuncMgr.CallBackFun():Tfunc
    var 
       CallFun: Tfunc;
       libHandle: THandle;
    begin
      libHandle :=LoadLibrary(PChar('test.dll'));
      Result := GetProcAddress(libHandle, PChar('Max')); 
    end;
      

  2.   

    因为你在函数CallBackFun中定义的变量CallFun: Tfunc;为局部变量,内存分配在栈上,当函数调用完成后,内存也就释放了,这个时候内存可能被其他地方调用,也就是说你返回的地址当你再调用时指向的不一定还是你dll函数的地址了。
      

  3.   

    还有个问题:
    type
       Tfunc = function (sParam:String): Boolean; stdcall;函数的定义不要用string改为type
       Tfunc = function (sParam: PChar): Boolean; stdcall;
      

  4.   

    应该不是局部变量内存自动释放问题,我调试过,调用处的函数地址,和 GetProcAddress(libHandle, PChar('Max')); 返回的地址是一样的
      

  5.   


    楼主,我测试没问题,如下:
    unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      Tfunc = function (sParam: string): Boolean; stdcall;  TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Edit2: TEdit;
        Memo1: TMemo;
        Button2: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        { Private declarations }
        aFun: TFunc;
      public
        { Public declarations }
        function CallBackFun: Tfunc;
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
      //
    end;function TForm1.CallBackFun: Tfunc;
    var
      CallFunc: Tfunc;
      libHandle: THandle;
    begin
      libHandle := LoadLibrary(PChar('Project1.dll'));
      @CallFunc := GetProcAddress(libHandle, PChar('Test'));
      Result := CallFunc;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      aFun := Pointer(CallBackFun);//保存函数地址
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      if aFun('123') then//调用
        ShowMessage('True')
      else
        ShowMessage('False');
    end;end.
      

  6.   

    libHandle := LoadLibrary(PChar('\Project1.dll'));
      

  7.   

    libHandle := LoadLibrary(PChar('\Project1.dll'));
    试试,刚看到教材这样说的,不知道,自己试试看
      

  8.   

    http://v.ku6.com/show/3MuZe-LQK2ouHWEXYN3Vqw...html?from=my