[Rtti] Invoke (ffi.manager implemention) and records as arguments
Summary
ffi.manager have a few bugs around passing records as arguments for example
program project1;
{$mode delphi}
{$H+} {$M+}
{$RTTI EXPLICIT METHODS([vcPublished]) PROPERTIES([vcPublished]) FIELDS([vcPublished])}
uses
SysUtils, TypInfo, Rtti, ffi.manager;
type
TRec2 = record
P: Pointer;
Intf: IUnknown;
B: Byte;
end;
type
{ TMyObj }
TMyObj = class
strict private
FStr: string;
public
constructor Create;
published
procedure Test2Const(const ARec: TRec2); //you get garbage in ARec
end;
var
ErrorCount: Integer;
procedure Check(ACondition: boolean; const AMessage: string);
begin
if not ACondition then
begin
WriteLn('ERROR: ' + AMessage);
INc(ErrorCount);
end;
end;
var
Intf: IUnknown;
{ TMyObj }
constructor TMyObj.Create;
begin
FStr := '123';
end;
procedure TMyObj.Test2Const(const ARec: TRec2);
begin
Check(FStr = '123', 'Test2Const: Self is broken');
Check(ARec.Intf = Intf, 'Test2Const: ARec is broken');
Check(ARec.B = 59, 'Test2Const: ARec is broken');
end;
procedure ZeroRecord(var Rec; ATypeInfo: PTypeInfo);
begin
FinalizeArray(@Rec, ATypeInfo, 1);
FillChar(Rec, GetTypeData(ATypeInfo).RecSize, 0);
end;
var
O: TMyObj;
Context: TRttiContext;
R2: TRec2;
begin
O := TMyObj.Create;
Intf := TInterfacedObject.Create;
try
Context := TRttiContext.Create;
try
R2.Intf := Intf;
R2.B := 59;
Context.GetType(TMyObj).GetMethod('Test2Const').Invoke(O, [TValue.From<TRec2>(R2)]);
finally
Context.Free; O.Free;
end;
if ErrorCount > 0 then
Halt(ErrorCount);
WriteLn('OK');
except
on E: Exception do
begin
WriteLn(E.ClassName + ': ' + E.Message);
Halt(1);
end;
end;
end.
System Information
- Operating system: Linux
- Processor architecture: x86-64
- Compiler version: trunk
Steps to reproduce
patch and full test be added in next commit