I’m creating an instance of a class using the TRttiMethod.Invoke function , but when the constructor or a method is overloaded, the rtti does not call the proper method.
I wrote a sample app to ilustate my problem.
program ProjectFoo;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Rtti,
System.SysUtils;
type
TFoo=class
public
constructor Create(Value : Integer);overload;
constructor Create(const Value : string);overload;
function Bar(value : integer) : Integer; overload;
function Bar(const value : string) : string; overload;
end;
{ TFoo }
constructor TFoo.Create(Value: Integer);
begin
Writeln(Value);
end;
function TFoo.Bar(value: integer): Integer;
begin
Writeln(Value);
Result:=value;
end;
function TFoo.Bar(const value: string): string;
begin
Writeln(Value);
Result:=value;
end;
constructor TFoo.Create(const Value: string);
begin
Writeln(Value);
end;
var
c : TRttiContext;
t : TRttiInstanceType;
r : TValue;
begin
try
c := TRttiContext.Create;
t := (c.GetType(TFoo) as TRttiInstanceType);
r := t.GetMethod('Create').Invoke(t.MetaclassType,[444]);//this works
//r := t.GetMethod('Create').Invoke(t.MetaclassType,['hello from constructor string']);//this fails : EInvalidCast: Invalid class typecast
t.GetMethod('Bar').Invoke(r,[1]);// this works
//t.GetMethod('Bar').Invoke(r,['Hello from bar']); //this fails : EInvalidCast: Invalid class typecast
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.
This is a RTTI bug? or exist another way to call the overloaded methods of a class using the RTTI?
There is nothing wrong with the
TRttiMethod.Invokemethod, your issue is located in theGetMethod. This function internally call to theTRttiType.GetMethodsand retrieves a pointer to the first method which match with the name passed as parameter. So when you are executing this codet.GetMethod('Create')you always are getting a pointer to the same method.To execute an overloaded version of the constructor or another method you must resolve the method address to execute based in the parameters, and then call the
TRttiMethod.Invokefunction.Check this sample function.
Now you can call the constructors or methods of your class in one of these ways