Skip to content

Fix for calling constructors via RTTI if the class overrides NewInstance

Here is a sample code for Delphi/FPC:

program Project1;

{$ifdef FPC}
{$mode objfpc}{$H+}
{$RTTI EXPLICIT
  METHODS([vcPublic,vcPublished])}
{$else}
{$APPTYPE CONSOLE}
{$endif}

uses
  SysUtils, Rtti;

type
  TTestBase = class   
    public
      class function NewInstance: TObject; override;
  end;

  TTest = class(TTestBase)
    public
      class function NewInstance: TObject; override;
  end;

var
  obj: TTest;

{ Test }

class function TTestBase.NewInstance: TObject;
begin
  Result := inherited NewInstance;
  WriteLn('TTestBase.NewInstance');
end;

class function TTest.NewInstance: TObject;
begin
  Result := inherited NewInstance;
  WriteLn('TTest.NewInstance');
end;

begin
  obj := TTest(TRttiContext.Create{$ifdef FPC}(False){$endif}.GetType(TTest)
    .GetMethod('Create').Invoke(TTest, []).AsObject);
  WriteLn('...');
  obj := TTest(TRttiContext.Create{$ifdef FPC}(False){$endif}.GetType(TTest)
    .GetMethod('Create').Invoke(TTestBase, []).AsObject);
  ReadLn;
end.

Here is a sample code for Delphi/FPC: The output in Delphi would be like this:

TTestBase.NewInstance
TTest.NewInstance
...
TTestBase.NewInstance

Output in FPC:

...

rtti_newinstance.patch

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information