Jump to content
Sonjli

RTTI Context can't find an interface

Recommended Posts

Hello. In this source

unit Unit2;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,
  Spring.Collections;

type
  IScarafuglio = interface(IInvokable)
    ['{8E5CC1F0-8759-4965-BF83-0C2DC5E1153C}']
    function Nome: string;
    function cognome: string;
    function Eta: Integer;
  end;

  IPippo = interface(IInvokable)
    ['{C6B11B79-F08C-47D0-9E21-EBE4788E43E1}']
    function PlutoList: IReadOnlyList<IScarafuglio>;
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  a: IPippo;
begin
  // Use the RTTI in Unmarshal
  a := Unmarshal<IPippo>(
    '''
    {
      "PlutoList": [
        {
        "Nome": "Eddy",
        "cognome": "Mazzarini",
        "Eta": 22
        },
        {
        "Nome": "Luca",
        "cognome": "Vecchiato",
        "Eta": 56
        }
      ]
    }
    '''
    );

  ShowMessage(a.PlutoList[1].Nome); // AV because IScarafuglio instance is nil
end;

end.

the interface IScarafuglio is never found with

Context.FindType('Unit2.IScarafuglio');

The result i always nil.

But if I add a simple field or anything else that reference the IScarafuglio in interface, then everything is fine:

 

unit Unit2;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,
  Spring.Collections;

type
  IScarafuglio = interface(IInvokable)
    ['{8E5CC1F0-8759-4965-BF83-0C2DC5E1153C}']
    function Nome: string;
    function cognome: string;
    function Eta: Integer;
  end;

  IPippo = interface(IInvokable)
    ['{C6B11B79-F08C-47D0-9E21-EBE4788E43E1}']
    function PlutoList: IReadOnlyList<IScarafuglio>;
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    XYZ: IScarafuglio; // From now everything is fine and RTTI "know" who IScarafuglio is... 
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  a: IPippo;
begin
  // Use the RTTI in Unmarshal
  a := Unmarshal<IPippo>(
    '''
    {
      "PlutoList": [
        {
        "Nome": "Eddy",
        "cognome": "Mazzarini",
        "Eta": 22
        },
        {
        "Nome": "Luca",
        "cognome": "Vecchiato",
        "Eta": 56
        }
      ]
    }
    '''
    );

  ShowMessage(a.PlutoList[1].Nome); // WORKING!!!
end;

end.

Why this behaviour?

 

Thanks

Share this post


Link to post

Why look up the type by full-qualified name in the first place? Every spring collection has the ElementType property that returns a PTypeInfo.

Share this post


Link to post
16 hours ago, Stefan Glienke said:

Why look up the type by full-qualified name in the first place? Every spring collection has the ElementType property that returns a PTypeInfo.

This was not the point, for me. I just would like to know why the RTTI doesn't know nothing about IScarafuglio until it is declared.

Anyway I am looking for the use of that prop in my code.

Share this post


Link to post
Posted (edited)

It is because the compiler does not keep typeinfo of types that are only used as generic parameters in generic types in the public typeinfo list (which is what FindType with a qualified name iterates).

If you had included the code for that Unmarshal I could probably give more advice on how to implement it best given that you seem to have support for spring collections in there

Edited by Stefan Glienke
  • Thanks 1

Share this post


Link to post
5 minutes ago, Stefan Glienke said:

It is because the compiler does not keep typeinfo of types that are only used as generic parameters in generic types in the public typeinfo list (which is what FindType with a qualified name iterates).

If you had included the code for that Unmarshal I could probably give more advice on how to implement it best given that you seem to have support for spring collections in there

Yes. The code is in FidoLib (I collaborate in the project).

The file is this: https://github.com/mirko-bianco/FidoLib/blob/develop/source/Json/Fido.JSON.Marshalling.pas

  • Like 1

Share this post


Link to post

Nice, never heard of it before but I enjoy looking at libraries that have Spring as their dependency :classic_cool:  I submitted some improvement suggestions in the area we discussed here.

  • Thanks 1

Share this post


Link to post
50 minutes ago, Stefan Glienke said:

Nice, never heard of it before but I enjoy looking at libraries that have Spring as their dependency :classic_cool:  I submitted some improvement suggestions in the area we discussed here.

Very strange you never heard about FidoLib: the best library after the invention of programming (and Sprign4d, for sure :classic_tongue:)

jokes apart, Thanks for your help!

  • Haha 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×