Delphi: Call a function whose name is stored in a string

后端 未结 10 1340
旧时难觅i
旧时难觅i 2020-12-08 05:30

Is it possible to call a function whose name is stored in a string in Delphi?

相关标签:
10条回答
  • 2020-12-08 05:52

    If you are asking if there is something like the JavaScript eval() is possible in Delphi, no this is not (easily) achievable since Delphi compiles to native code.

    If you need only to support some strings you can always do many if or a case... Something like:

    if myString = 'myFunction' then
        myFunction();
    
    0 讨论(0)
  • 2020-12-08 05:56

    I'm surprised no one has suggested a dispatch table. This is exactly what it's for.

    program RPS;
    
    uses
      SysUtils,
      Generics.Collections;
    
    type
      TDispatchTable = class(TDictionary<string, TProc>);
    
    procedure Rock;
    begin
    end;
    
    procedure Paper;
    begin
    end;
    
    procedure Scissors;
    begin
    end;
    
    var
      DispatchTable: TDispatchTable;
    
    begin
      DispatchTable := TDispatchTable.Create;
      try
        DispatchTable.Add('Rock', Rock);
        DispatchTable.Add('Paper', Paper);
        DispatchTable.Add('Scissors', Scissors);
    
        DispatchTable['Rock'].Invoke; // or DispatchTable['Rock']();
      finally
        DispatchTable.Free;
      end;
    end.
    

    The implementation I wrote uses generics so it would only work with Delphi 2009+. For older versions it would probably be easiest to implement using TStringList and the command pattern

    0 讨论(0)
  • 2020-12-08 05:57
    function ExecuteMethod(AClass : TClass; AMethodName : String; const AArgs: Array of TValue) : TValue;
    var
      RttiContext : TRttiContext;
      RttiMethod  : TRttiMethod;
      RttiType    : TRttiType;
      RttiObject  : TObject;
    begin
      RttiObject := AClass.Create;
      try
        RttiContext := TRttiContext.Create;
        RttiType    := RttiContext.GetType(AClass);
        RttiMethod  := RttiType.GetMethod(AMethodName);
        Result      := RttiMethod.Invoke(RttiObject,AArgs);
      finally
        RttiObject.Free;
      end;
    end;
    
    0 讨论(0)
  • 2020-12-08 05:58

    You can do something like this by crafting one or more classes with published properties that use functions to implement their read and write functionality. The properties can then be discovered using RTTI reflection and referenced, causing the underlying functions to get called.

    Alternatively, you can store function pointers in a table, or even the Object property of TStringList and effectively index them by string name.

    Straight calling of a function by name is not possible in Delphi.

    0 讨论(0)
提交回复
热议问题