1

How to access the private method TStreamReader.FillBuffer in Delphi 10.1 Berlin, we did it with a class helper before 10.1 - but the proposed solution does not work:

uses System.Rtti;
procedure TForm1.FormCreate(Sender: TObject);
begin
  Assert(Assigned(TRttiContext.Create.GetType(TStreamReader).GetMethod('FillBuffer')), 
    'Failed');
end;

it fails just because GetMethod returns NIL. Any ideas why this fails?

Edited: I do want to know WHY it fails

cydo
  • 187
  • 2
  • 10
  • It probably fails because it was not compiled with extended RTTI enabled. – Rudy Velthuis Jun 17 '16 at 06:28
  • 2
    Have you seen @LURD's answer here: http://stackoverflow.com/questions/36716363/how-to-access-private-methods-without-helpers/37761852#37761852 – MartynA Jun 17 '16 at 06:30
  • @Rudy: I've tried adding {$METHODINFO ON} in my unit1.pas but I think this should be done in system.classes (where TStreamReader is declared). – cydo Jun 17 '16 at 08:06
  • @MartynA: `TMethod(P).Code := @TStreamReader.FillBuffer` does work, thank you please add as an answer – cydo Jun 17 '16 at 08:33
  • Glad it worked, but I think it would be better if you add your own answer, as I don't know what code you ended up using exactly. – MartynA Jun 17 '16 at 08:44
  • We don't need to keep replicating answers to the same question @MartynA, closing as a duplicate is the correct thing to do – David Heffernan Jun 17 '16 at 09:02
  • @DavidHeffernan: Fine, but I'm not convinced it is a duplicate. The OP asks " GetMethod returns NIL. Any ideas why this fails?" which the other q doesn't address nor answer, afaics. – MartynA Jun 17 '16 at 12:02
  • @DavidHeffernan: The private fields are visible with GetFields, but the private methods not. There is no $METHODINFO ON for this class which would be the answer to the question I think.... therefore it is not a duplicate question – cydo Jun 17 '16 at 12:23
  • See also [RTTI access to private methods of VCL, e.g. TCustomForm.SetWindowState](http://stackoverflow.com/q/37905306/576719). – LU RD Jun 19 '16 at 10:09

1 Answers1

1

It fails because the private methods aren't included in this class. See RTTI access to private methods of VCL, e.g. TCustomForm.SetWindowState

There is a workaround for getting the private method though:

See: How to access private methods without helpers?

type
  TStreamReaderHelper = class helper for TStreamReader
  public
    procedure FillBuffer(var Encoding: TEncoding);
  end;

procedure TStreamReaderHelper.FillBuffer(var Encoding: TEncoding);
var
  Method: procedure(var Encoding: TEncoding) of object;
begin
  TMethod(Method).Code := @TStreamReader.FillBuffer;
  TMethod(Method).Data := Self;
  Method(Encoding);
end;
Community
  • 1
  • 1
cydo
  • 187
  • 2
  • 10