type
  TaClass = class
  public
    procedure AProc; 
  end;var
  PtrOfAProcAddr : Pointer;求将AProc的地址赋给PtrOfAProcAddr

解决方案 »

  1.   

    PtrOfProcAddr := @AProc
    如果要通过PtrOfProcAddr调用AProc,
    最好定义类型TAProc = proc of object;...
      

  2.   

    AProc是类里面的方法,每个实例就会有一个,而PtrOfAProcAddr是全局变量,如果生成多个类实例,那PtrOfAProcAddr指向那个实例的指针了?如果只是生成一个实例,像Application一样,那很简单。  TaClass = class
      public
        procedure AProc; 
        constructor Create;
      end;constructor TaClass.Create;
    begin
      inherited Create;
      PtrOfAProcAddr := @AProc;
    end;...
    而且一般来说不是定义成PtrOfAProcAddr: Pointer
    是这样:
    type
      TProcEvent = procedure of object;var
      PtrofAProcAdd: TProcEvent;那么这样,PtrOfAProcAddr和AProc就遥相呼应了。
      

  3.   

    同意 copy_paste ,顺便把贴转到技术区,技术贴就不要放在非技术区啊~~~
      

  4.   

    你好像是C出身的,那应该明白函数指针的使用,你上面所说的Pointer指向一个类里面的方法,但pascal不一样,它的类方法/函数的声明类型中是应该加上 of object的,如:type
      TNotifyEvent = procedure (Sender: TObject) of object;如是C/C++的话,只是:
    typedef void (*NOTIFYEVENT)();
    而CB中对应加了(__closure)参数,和标准C不同,和VC也不同。
    typedef void __fastcall (__closure *TNotifyEvent)(TObject* Sender);Pointer是可以转成对procedure of object之类的类型指针,不同有点麻烦,所以一般来说VCL很多的全局方法/函数指针都有明确的类型,而不是Pointer,底层一点就是用Pointer,但所对应的就不是类里面的方法,而是具体的:
    procedure Proc;
    function Func: Pointer;
      

  5.   

    procedure TForm1.Button1Click(Sender: TObject);var
      ta: Taclass;
      PtrOfAProcAddr : Pointer;begin
      ta:= Taclass.Create;
      PtrOfAProcAddr:= ta.MethodAddress('Aproc');
      ShowMessage(format('%d', [integer(@PtrOfAProcAddr)]));
      ta.Free;
    end;
      

  6.   

    MethodAddress、FieldAddress只指取类里的published的属性、方法、函数的指针
      

  7.   

    当声明为
    var
      PtrOfAProcAddr : Pointer;
    时PtrOfAProcAddr := @AProc;
    不能通过编译。当声明为
    type
      TClassProcedure = procedure of object;var
      PtrOfAProcAddr : TClassProcedure;
    可以
      PtrOfAProcAddr := AProc;不过得到的是TMethod纪录,要得到它的地址,还需要进一步操作。var
      ClassProc: TClassProcedure;
      P: ^TMethod;
      PtrOfAProcAddr: Pointer;
    begin
      ClassProc := AProc;  
      P := @ClassProc;
      PtrOfAProcAddr := P^.Code;
    end;
    不过我的主要目的不是这个。我要做一个这样的函数:
    function GetClassMethodAddr(var aMethod: TClassProcedure): Pointer;
    var
      MethodPtr: ^TMethod;
    begin
      MethodPtr := @aMethod;
      Result := MethodPtr^.Code;
    end;但,假如要取下面的B函数的地址:type
      TaClass = class
        function BProc: Integer;
      end;  type
      TClassFunction = function of object;就必须再写一个这样的函数,
    function GetClassMethodAddr(var aMethod: TClassFunction): Pointer;如果参数不同,还需要为每一个声明写一个函数。有没有办法只需一个声明,就可以让aMethod满足所有的类过程或函数的参数。
    不知道说清楚了没有
      

  8.   

    use
    PtrOfAProcAddr :=MakeObjectInstance(TaClass.MethodName)
    ok
      

  9.   

    学习!
    To  copy_paste(木石三):
    我修改public成published,得出得结果一样,怎解?
    谢谢!!!
      

  10.   

    MakeObjectInstance只是用来建造一个Thunk函数的,和我的问题有点不相关。
    我是想得到函数的地址,不是再建造一个函数。不过还是谢谢你的参与。再一次谢谢。
    也谢谢大家
      

  11.   

    关于MethodAddress和FieldAddress,如copy_paste大老说的那样,
    只对published的property和event有效。
      

  12.   

    TMethod应该不是这样用的,我以前看VCL做的时候也不太明白,例子太少,你要做成通过的过程比较麻烦,你如果是为了做回调的话,应该很多方法,此路比较难通。
      

  13.   

    type
      TAClass = class
      published
        procedure AProc;      //published关键字不可少
      public
        function BProc: Integer;
        constructor Create;
      end;procedure TForm1.Button1Click(Sender: TObject);
    var
      P: pointer;
      A: TAClass;
    begin
      A := TAClass.Create;
      P := A.MethodAddress('AProc');
      if Assigned(P) then
        Caption := Format('%p', [P]);
      A.Free;
    end;如果想多知道些这么东西,看看这里介绍:
    http://www.delphibbs.com/delphibbs/dispq.asp?lid=1642063
      

  14.   

    好像是这样了,你看看对不对了。type
      TAClass = class
      private
        FAddrA: Pointer;
        FAddrB: Pointer;
      public
        procedure AProc;
        function BProc: Integer;
        constructor Create;
        property AddrA: Pointer read FAddrA;
        property AddrB: Pointer read FAddrB;
      end;  TProcEvent = procedure of object;
      TFuncEvent = function: Integer of object;
    { TAClass }procedure TAClass.AProc;
    begin
      ShowMessage('AProc');
    end;function TAClass.BProc: Integer;
    begin
      Result := 0;
      ShowMessage('BProc');
    end;function GetMethod(ACode: Pointer; AData: Pointer = nil): Pointer; // result is PMethod
    var
      Data: ^TMethod;
    begin
      New(Data);
      Result := Data;
      Data.Code := ACode;
      Data.Data := AData;
    end;constructor TAClass.Create;
    var
      Proc: TProcEvent;
      Func: TFuncEvent;
    begin
      inherited Create;
      Proc := AProc;
      FAddrA := Some(@Proc);  Func := BProc;
      FAddrB := Some(@Func);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      P: ^TMethod;
      Proc: TProcEvent;
      Func: TFuncEvent;
      A: TAClass;
    begin
      A := TAClass.Create;
      P := A.AddrA;
      TMethod(Proc).Code := P^.Code;
      TMethod(Proc).Data := P^.Data;
      Proc();  P := A.AddrB;
      TMethod(Func).Code := P^.Code;
      TMethod(Func).Data := P^.Data;
      Caption := IntToStr(Func());
      A.Free;
    end;
      

  15.   

    函数打错了。呵
    constructor TAClass.Create;
    var
      Proc: TProcEvent;
      Func: TFuncEvent;
    begin
      inherited Create;
      Proc := AProc;
      FAddrA := GetMethod(@Proc);  Func := BProc;
      FAddrB := GetMethod(@Func);
    end;
      

  16.   

    谢谢,copy_paste。
    你的程序是可以正常运行,但是也只是在TaClass的函数体内执行。如果再在下面这个函数体内执行aMethod,你怎么办呢?procedure CallMethod(aObject: TaClass; aMethod: TProcEvent);
    beginend;你最终还是要转换成我的那种办法。而且你的办法也不能逃脱用TProcEvent来避开
    编译器的语法检查。好像是没有办法直接得到函数的地址。像@操作符那样。
      

  17.   

    简单点,类的函数/方法是我现在是没有找到可以直接得到它地址的方法,也许有人知道。我也不清楚的你的要求,我说过,如果是要回调,方法N多,此路N难。procedure TForm1.Button1Click(Sender: TObject);
    var
      ThreadID: DWORD;
      P: function(P: Pointer): DWORD of object;
    begin
      P := ThreadFunc;
      CloseHandle(Createthread(nil, 0, @P, nil, 0, ThreadID));
    end;function TForm1.ThreadFunc(Param: Pointer): DWORD;
    var
      P2: function(P: Pointer): DWORD of object;
    begin
      P2 := ThreadFunc;
      Result := 0;
      MessageBox(0, 'Thread Hello', 'ok', MB_OK);
    end;
      

  18.   

    好象要在方法前加类名
    type
      TaClass = class
      public
        procedure AProc; 
      end;var
      PtrOfAProcAddr : Pointer;proceudre test
    begin
      PtrOfAProcAddr := @TaClass.AProc;
    end;
      

  19.   

    哎呀,我的救世主啊,你终于来啦,
    告诉我,Delphi帮助文件中的主题是什么?
    你的办法还真的行啊,爽啊,今天晚上喝酒喝的爽啊,爽啊我本来是着这样想的
    PtrOfAProcAddr := @(TaClass.AProc);
    不行,就没再试了,但怎么没有试试@TaClass.AProc,哎,无所谓,放分嘛,
    爽ingcopy_paste大佬,辛苦了,
    同志们,辛苦啦
    鸣谢(字母序):
    ========================
    copy_paste大佬
    ehom大佬
    fancier大佬
    Kingron大佬
    NightCloud大佬
    nobition大佬
    qiume大佬
    selly大佬
    SGP大佬
    xiaocha大佬
    为了答谢SGP大佬的正确答案,以另开一帖请您接分,请移步:
    http://expert.csdn.net/Expert/topic/1481/1481646.xml?temp=.1861536
      

  20.   

    没见过这种用法,不过居然编绎通过,觉得它是类似静态函数的表达的意思,如果是这样,那你无所谓类方法/函数,直接写个函数/方法就行了,因为你这样做,运行时,如果访问类的变量,就会出错。
    type
      TMyClass = class
      private
        FValue: Integer;
      public
        procedure B;
      end;procedure TMyClass.B;
    begin
      FValue := 10;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      P: Pointer;
    begin
      P := @TFormDD.B;
      TProcedure(P)();
    end;不要告诉我,你专门写了个类,全是静态的方法/函数