(...as TMethodName) .. again

Hi experts!

I want to back to my old problem.. first you need to read this:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20886881.html

Now.. I have a problem with implement function..

type
TDynamicFunction = Procedure: String of Object;

Above declaration is incorrect and Delphi don`t want to compile...

But..

type
TDynamicFunction = Function: String of Object;

is correct ! .. but when I want to "call" it by @ Method Addres I always get NIL ... Could you help me and show one example how to use "Method Adress" with functions ?

PS: sorry for my bad language..
LVL 2
DetiAsked:
Who is Participating?
 
Russell LibbyConnect With a Mentor Software Engineer, Advisory Commented:
type
  TDynaFunc         =  Function: String of object;
  TDynaFuncParam    =  Function(Param: String): String of object;

type
  TForm1            =  class(TForm)
     Button1:       TButton;
     procedure      FormCreate(Sender: TObject);
  private
     // Private declarations
  public
     // Public declarations
     function       CallDynamicParam(DynaName: String; Param: String): String;
     function       CallDynamic(DynaName: String): String;
  published
     // Published declarations. NOTE: In order for RTTI to work, you must put
     // the dynamic functions in the published section
     function       FooParam(Param: String): String;
     function       BarParam(Param: String): String;
     function       Foo: String;
     function       Bar: String;
  end;

function TForm1.Foo: String;
begin
  result:='Foo';
end;

function TForm1.Bar: String;
begin
  result:='Bar';
end;

function TForm1.FooParam(Param: String): String;
begin
  result:=AnsiUpperCase(Param);
end;

function TForm1.BarParam(Param: String): String;
begin
  result:=AnsiLowerCase(Param);
end;

function TForm1.CallDynamicParam(DynaName: String; Param: String): String;
var  dynaFunc:   TDynaFuncParam;
begin

  // To pacify the compiler warnings
  dynaFunc:=nil;
  try
     // Get method address
     @dynaFunc:=MethodAddress(DynaName);
     // Check assignment
     if Assigned(@dynaFunc) then
        // Call function
        result:=dynaFunc(Param)
     else
        // Nil function
        result:='';
  except
     // Failure
     result:='';
  end;

end;

function TForm1.CallDynamic(DynaName: String): String;
var  dynaFunc:   TDynaFunc;
begin

  // To pacify the compiler warnings
  dynaFunc:=nil;
  try
     // Get method address
     @dynaFunc:=MethodAddress(DynaName);
     // Check assignment
     if Assigned(@dynaFunc) then
        // Call function
        result:=dynaFunc
     else
        // Nil function
        result:='';
  except
     // Failure
     result:='';
  end;

end;

--------------------


  ShowMessage(CallDynamic('Foo'));
  ShowMessage(CallDynamicParam('FooParam', 'hahaha'));

--------------------

Russell
0
 
shaneholmesCommented:
like this:

TDynamicFunction = Procedure (value: String) of Object;

TDynamicFunction = Procedure (var value: String) of Object;


Shane
0
 
shaneholmesCommented:
but then you will need a varibale of type TDynamicFunction

var DynFunc: TDynamicFunction;


or in your form

TfrmMain = class(TForm)
  private
    { Private declarations }
    DynFunc: TDynamicFunction;
  public
    { Public declarations }
  end;


SHane
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
shaneholmesCommented:
Oops sorry, then -  @DynFunc


Shane
0
 
DetiAuthor Commented:
Yes yes.. but this is not what I wanted... I want to function.. to result some value.. as I wrote:

ype
TDynamicFunction = Procedure: String of Object;

Above declaration is incorrect and Delphi don`t want to compile...

But..

type
TDynamicFunction = Function: String of Object;

.. always get NUL :(

Give me some working example... and 400 points are yours.. :)
0
 
shaneholmesCommented:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type

  TDynFunc = function : String of Object;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    fDynFunc: TDynFunc;
  public
    { Public declarations }
    function MyDynFunct: String;
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.MyDynFunct: String;
begin
 //
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 fDynFunc:= MyDynFunct;
end;


Shane
0
 
Russell LibbySoftware Engineer, Advisory Commented:

You need to expose the dynamic functions in the published section for RTTI to work

type
  TDynamicFunction  =  Function: String of object;

type
  TForm1            =  class(TForm)
     procedure      FormCreate(Sender: TObject);
  private
     // Private declarations
  public
     // Public declarations
     function       CallDynamic(DynaName: String): String;
  published
     // Published declarations. NOTE: In order for RTTI to work, you must put
     // the dynamic functions in the published section
     function       Foo: String;
     function       Bar: String;
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

function TForm1.Foo: String;
begin
  result:='Foo';
end;

function TForm1.Bar: String;
begin
  result:='Bar';
end;

function TForm1.CallDynamic(DynaName: String): String;
var  dynaFunc:   TDynamicFunction;
begin

  try
     // Get method address
     @dynaFunc:=MethodAddress(DynaName);
     // Check assignment
     if Assigned(@dynaFunc) then
        // Call function
        result:=dynaFunc
     else
        // Nil function
        result:='';
  except
     // Failure
     result:='';
  end;

end;

this allows for calling like

result:=Form1.CallDynamic('Foo');
result:=Form1.CallDynamic('Bar');

-------------

Regards,
Russell




0
 
shaneholmesCommented:
Yup! For RTTI to work

Shane
0
 
shaneholmesCommented:
Yup! For RTTI to work

Shane
0
 
kretzschmarCommented:
listening . . . all said

(sorry for the typo of the previous q (procedure -> function))

0
 
DetiAuthor Commented:
Yess - it works - it is okej .. points for rllibby of course.. - for the end.. could you give me some example for using function with parameter. ?

function SomeF(s: string): string;

I don`t know what is wrong:

------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TDynamicFunction  =  Function: String of object;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
  function CallDynamic(DynaName: String): String;
    { Public declarations }
  published

  function       Foo(s: string): String; // here you have some...
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.Foo(s: string): String;
begin
  result:=AnsiUpperCase(s);
end;

function TForm1.CallDynamic(DynaName: String): String;
var  dynaFunc:   TDynamicFunction;
begin

  try
     // Get method address
     @dynaFunc:=MethodAddress(DynaName);
     // Check assignment
     if Assigned(@dynaFunc) then
        // Call function
        result:=dynaFunc
     else
        // Nil function
        result:='';
  except
     // Failure
     result:='';
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Form1.CallDynamic('Foo(''hahaha'')')); // is it correct ?


end;

end.

Above should give me Message 'HAHAHA' ... but returns '' :(
0
 
kretzschmarCommented:
this should be already discussed in the previous q
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.