2

In Delphi (Tokyo) we have :

  THashSHA2 = record
  private
    ...
    function GetDigest: TBytes;
    procedure Update(const AData: PByte; ALength: Cardinal); overload;
  public
    ...
  end;

Is there a way to access the function GetDigest / Update ? Not via RTTI, as this will be much too slow. I need something fast like if the procedure was public.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
zeus
  • 12,173
  • 9
  • 63
  • 184
  • Smells like an XY problem – Dave Nottage Jan 21 '18 at 20:02
  • I wouldn't say it's a good duplicate. It says "without helpers" which leads to RTTI. This question wants to avoid RTTI. – Victoria Jan 21 '18 at 20:33
  • 1
    @victoria That isn't a material difference. The question here is more specific but is covered by the more general dupe. – David Heffernan Jan 21 '18 at 23:38
  • I wouldn't call that a "general dupe" either. This question specifically asks for not using RTTI. What's more, accepted answer here is not accurate, as you can do that by the mentioned leak (I'd post one, but cannot). – Victoria Jan 21 '18 at 23:48
  • @Victoria: the answers to the duplicate also cover other ways that do not require RTTI. The fact that the *accepted* answer uses RTTI doesn't change that; some of the others don't. The helper and "with Self do", **inlined**, are mentioned too. And that solution does not cause any overhead at all. – Rudy Velthuis Jan 22 '18 at 00:00
  • @Rudy, you might be right here. But anyway, I said the accepted answer here is not accurate. There is a way, that undocumented leak. Not voting that post negatively, just saying :) – Victoria Jan 22 '18 at 00:15
  • FWIW: http://rvelthuis.blogspot.de/2018/01/accessing-private-methods-of-another.html – Rudy Velthuis Jan 22 '18 at 14:45
  • @RudyVelthuis thanks i will take a look – zeus Jan 22 '18 at 14:54

1 Answers1

3

You actually placed two different questions here:

  1. Is there a way to access efficiently private procedure/function of a record?

No. There is no general and efficient way to access (any) private proc/func.

  1. Is there a way to access the function GetDigest / Update ?

Yes. Public function HashAsBytes can/should be used instead of GetDigest.

function HashAsBytes: TBytes; inline;

Public procedures Update can/should be used instead of private one.

procedure Update(const AData; ALength: Cardinal); overload;

procedure Update(const AData: TBytes; ALength: Cardinal = 0); overload; inline;

procedure Update(const Input: string); overload; inline;
Andrei Galatyn
  • 3,322
  • 2
  • 24
  • 38
  • thanks Andrei, was a bad example i took because yes we can access with other funtions (thanks to point it). But the main idea was to ask how to access private functions in general – zeus Jan 21 '18 at 20:18
  • 1
    There is a way, by `record helper` you can declare `inline` method that will in its implementation invoke private method by the famous leak `with Self do ThePrivateMethod;`. – Victoria Jan 21 '18 at 20:29
  • @victoria, hmmm I didn't know about this leak ? – zeus Jan 21 '18 at 20:53
  • @loki, it's great! You can access many (maybe all) helped type members. And if you inline the function, you reach a direct call. So there is actually non-official, efficient way to do what you want. – Victoria Jan 21 '18 at 20:56
  • @victoria Marco Cantu mentioned this hack to be closed. If you still able to use it in some scenarios (i can't check it right now), most probably it will impossible in future. http://blog.marcocantu.com/blog/2016-june-closing-class-helpers-loophole.html – Andrei Galatyn Jan 21 '18 at 21:18
  • @Andrei, works so far in Tokyo :) And it's difficult to say if that blog post talks about the `Self` one (I hope it does not). – Victoria Jan 21 '18 at 21:21
  • 1
    Andrei: there is. The "TMethod" trick and the "with Self do" trick are both efficient. – Rudy Velthuis Jan 21 '18 at 22:05
  • 1
    @Victoria: the blog post (by Marco Cantù) was made when the main loophole (using helper classes) was closed, a few versions ago. FWIW, you can also access the private method in an assembler helper method. So I found three workarounds. All require the use of a helper. I'll blog about them. – Rudy Velthuis Jan 22 '18 at 10:51