System.Rtti contains a lesser known, but powerful class TMethodImplementation, which is basically hidden and used in TVirtualMethodInterceptor. Outside this use, it cannot be created directly and it can only be accessed by TRttiMethod.CreateImplementation.
I recently discovered that Spring4d extends its use through a helper for TRttiInvokableType, so it can be used with standalone procedures and functions as well as with events. Here is a small console app showing how it can be used:
program MethodImplementationTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.TypInfo,
System.Rtti,
Spring;
type
TSimpleProc = function(I: Integer): Integer;
procedure ImplCallback(UserData: Pointer; const Args: TArray<TValue>;
out Result: TValue);
begin
WriteLn('From Implementation');
Result := Args[0].AsInteger * 2;
end;
var
Proc: TSimpleProc;
begin
ReportMemoryLeaksOnShutdown := True;
try
var RTTIContext := TRttiContext.Create;
var RTTIType := RTTIContext.GetType(TypeInfo(TSimpleProc));
var ProcImplementation := (RTTIType as TRttiInvokableType).CreateImplementation(nil, ImplCallback);
Proc := TSimpleProc(ProcImplementation.CodeAddress);
WriteLn(Proc(2));
ProcImplementation.Free;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
Output:
From Implementation
4
Simple and easy. Spring4D is full of gems. I wish the above functionality was part of the standard library.
I can think of many uses:
Python4Delphi contains a unit MethodCallback which uses complex assembly to convert methods into stubs that can be used with external C libraries. It could be rewritten using TMethodImplementation, without assembly code.
Also in Python4Delphi, the implementation of Delphi events using python code could be very much simplified and generalized using TMethodImplementation. You can create Delphi functions, procedures and methods, event handlers on the fly that are implemented by python code.
Similarly functionality can be provided with other scripting languages.