delpi中对象的一个方法能否作为一个参数(回调函数),传递给DLL中的函数.
可以提供实例最好了,谢谢!

解决方案 »

  1.   

    Dll中:
    type
      TCallback = function(AParam: Integer): Integer of object;function Test(Callback: TCallback): Boolean; stdcall;
    begin
      if Assigned(Callback) then
        Callback(1);
    end;exports
      Test;exe中:
    type
      TCallback = function(AParam: Integer): Integer of object;function Test(Callback: TCallback): Boolean; stdcall; extranal 'DllName.dll';procedure TForm1.CallBackTest(AParam: Integer);
    begin
      
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      Test(CallBackTest);
    end;
      

  2.   

    对象的方法作为回调函数调用的过程,得使用以下比较特殊的办法。(1) 先申明以下类型和过程:type
      TCallbackInstance = array [1..18] of Byte;       procedure MakeCallbackInstance(var Instance: TCallbackInstance;  ObjectAddr: Pointer;  FunctionAddr: Pointer);
    const CallbackCode: TCallbackInstance =
      ($8B,$04,$24,$50,$B8,$00,$00,$00,$00,$89,$44,$24,$04,$E9,$00,$00,$00,$00);
    begin
      Move(CallbackCode, Instance, SizeOf(TCallbackInstance));
      PInteger(@Instance[6])^ := Integer(ObjectAddr);
      PInteger(@Instance[15])^ := Integer(Integer(FunctionAddr) - Integer(@Instance) - 18);
    end;
    (2) 在设置回调时,申明一个TCallbackInstance类型变量,然后调用MakeCallbackInstance来生成变量值,将把该变量作为回调函数参数。type 
      TCallback = function(AParam: Integer): Boolean; function Test(Callback: TCallback): Boolean; stdcall; extranal 'DllName.dll'; procedure TForm1.CallBackTest(AParam: Integer);  stdcall;   //这个过程应该使用stdcall调用约定
    begin 
      ......
    end; procedure TForm1.FormCreate(Sender: TObject); 
    var
      Callback : TCallbackInstance;
    begin 
      MakeCallbackInstance(Callback, Self, @TForm1.Callbacktext);
      Test(@CallBack); 
    end;
      

  3.   

    3楼是说明了of object的意思
    也就是在普通回调函数中加了第一个参数为Self指针。
    我写的东西只适合在Delphi中使用,而3楼写的东西可以在其他语言之间调用,譬如exe用VC写,而dll用Delphi写。

    procedure TForm1.FormCreate(Sender: TObject); 
    var
      Callback : TCallbackInstance;
    begin 
      MakeCallbackInstance(Callback, Self, @TForm1.Callbacktext);
      Test(@CallBack); 
    end;
    中的Callback最好用VirtualProtect()设置成PAGE_EXECUTE的,貌似XP装了SP2之后如果启动的数据执行保护,这样的代码是执行不了的。
      

  4.   

    lake_cx 已经解释得很清楚了。如果DLL是用Delphi写的话,并且有源代码,则只需要在DLL的回调函数后加上of object申明,然后用lake_cx在一楼提供的代码,这是最简洁的。如果DLL不是用Delphi写的,或者不是自己写的,则只能使用我提供的这种方法了。