[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 257
  • Last Modified:

Dereferencing Method Pointer

I dont want to pass methods as parameter instead:(look at the if statement)

function GiveMeResult(value:integer):iinteger;
 
var
  Method1,Method2,MethodToUse:TMethod;

begin
   Method1.code:=MethodAddress('IsHere');
   Method1.data:=self;
   Method2.code:=MethodAddress('IsThere');
   Method2.data:=self;
      case value of
         0:MethodToUse:=Method1;
         1:MethodToUse:=Method2;
      end;

     if ((MethodToUse^('AnyParameter'))=true) then;
     result:1;
end;

but this is not working as it says semicolon or operator expected.
It does not work without dereferencing also.
Any way to determine which func to use. There is about 20 fucntios that will be referred to by MethodToUse.
thanks a lot
0
oalawna
Asked:
oalawna
  • 7
  • 3
1 Solution
 
oalawnaAuthor Commented:
btw, TMethod is a record type pointer.
0
 
Russell LibbySoftware Engineer, Advisory Commented:

It makes life much easier if the method pointers are of a specific layout (eg, all take X params that are the same data type).  This way, you can cast the TMethod record as that method type, and then call the method directly. An example:

type
  TDynaMethod    =  function(Value: Variant): Boolean of object; // Our method type
  TForm1         =  class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
     // Private declarations
  public
     // Public declarations
     function    GiveMeResult(Method: String; Param: Variant): Integer;
  published
     // Published declarations - methods that adhere to TDynaMethod
     function    IsHere(Value: Variant): Boolean;
     function    IsThere(Value: Variant): Boolean;
     function    IsSomewhere(Value: Variant): Boolean;
     function    IsNowhere(Value: Variant): Boolean;
     function    IsAnywhere(Value: Variant): Boolean;
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

function TForm1.GiveMeResult(Method: String; Param: Variant): Integer;
var  MethodAddr:    TMethod;
     DynaMethod:    TDynaMethod;
begin

  // Set data and code
  MethodAddr.Data:=Self;
  MethodAddr.Code:=MethodAddress(Method);

  // Check code assignment
  if Assigned(MethodAddr.Code) then
  begin
     // Cast as dynamethod
     DynaMethod:=TDynaMethod(MethodAddr);
     // Call method with param
     if DynaMethod(Param) then
        // Success
        result:=1
     else
        // Failure
        result:=0;
  end
  else
     // Failure
     result:=0;

end;

function TForm1.IsHere(Value: Variant): Boolean;
begin
  ShowMessage('IsHere');
  result:=True;
end;

function TForm1.IsThere(Value: Variant): Boolean;
begin
  ShowMessage('IsThere');
  result:=True;
end;

function TForm1.IsSomewhere(Value: Variant): Boolean;
begin
  ShowMessage('IsSomewhere');
  result:=True;
end;

function TForm1.IsNowhere(Value: Variant): Boolean;
begin
  ShowMessage('IsNowhere');
  result:=True;
end;

function TForm1.IsAnywhere(Value: Variant): Boolean;
begin
  ShowMessage('IsAnywhere');
  result:=True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

  GiveMeResult('IsHere', 1);
  GiveMeResult('IsThere', 'Testing');
  GiveMeResult('IsSomewhere', 10.234);

end;

Hope this helps. If not, perhaps you could more clearly describe what you are attempting to do.
Russell
0
 
oalawnaAuthor Commented:
Thanks. You are right. And my life is going to be easier because all 20 methods can be declared of the same type. they take same parameters and all return boolean. The solution is OK but how do you implement that DynaMethod? which is equivalent to my 20 methods.
The problem is that all methods are declared in a class and implemented already.i did this
  type
  TMyMethods=function(Aparameter:integer):boolean;
before the class declaration. Then defines the class methods in as fields like method1:TMyMethods.
but the implementation did not work .it was telling me that declaration different. I implemeted them like this:
function ClassName.Method3(Aparameter:integer):boolean;
begin
....
....
if........then
result:=true
end;
What am i missing here?
thank you
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Russell LibbySoftware Engineer, Advisory Commented:
You missed one crucial part... 'of object'

type
  TMyMethods=function(Aparameter:integer): boolean of object;

This declares the prototype as a method, and not a flat function.

Regards,
Russell
0
 
oalawnaAuthor Commented:
is not this funny?
thank you:-)
0
 
oalawnaAuthor Commented:
but should i change anything else because it is still telling me that declaration differs?
thanks
0
 
oalawnaAuthor Commented:
i added of object to the implemented methods
function ClassName.Method3(Aparameter:integer):boolean of object;
begin
end;
but with the same error.(with or without of object).
0
 
oalawnaAuthor Commented:
Ok it is working now.Forgot that those were pointers to the functions
0
 
Russell LibbySoftware Engineer, Advisory Commented:
Sounds like you got it working ('of object' on only on prototype, not on the actual methods), if not then let me know (and see the code) and we will get it worked out.

;-)
Russell

0
 
oalawnaAuthor Commented:
no no it is working:-)
but i am amazed that you can eventually cast a function not declared as any type to a method type if the parameters and return type is the same.
Words of a beginner:-)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now