Delphi 10.2.3 AccessViolation for Nullable type in Linux

Issue #301 wontfix
Inkvizi created an issue

Environment: Delphi 10.2.3, FMX, 64-bit Linux.

When I try get access to Nullable property of object by Rtti GetValue - I receive Access Violation in property getter. Code example:

unit TestNullable;

interface

uses
  DUnitX.TestFramework
  , Spring
  ;

type

  [TestFixture]
  TestNullableRttiLinux = class(TObject)
  strict private type
    TTestClass = class
    strict private
      FNullAbleStringField: TNullableString;
      function GetNullableStringField: TNullableString;
      procedure SetNullableStringField(const Value: TNullableString);
    public
      property NullableStringField: TNullableString read GetNullableStringField write SetNullableStringField;
    end;
  strict private
    FTestClass: TTestClass;
  public
    [Setup]
    procedure Setup;
    [TearDown]
    procedure TearDown;
    [Test]
    procedure TestReadNullAbleStringByRtti;
    [Test]
    procedure TestWriteNullAbleStringByRtti;
  end;

implementation

uses
  System.Rtti
  , Spring.Reflection
  , System.SysUtils
  , DUnitX.Assert.Ex
  ;

procedure TestNullableRttiLinux.Setup;
begin
  FTestClass := TTestClass.Create;
end;

procedure TestNullableRttiLinux.TearDown;
begin
  FTestClass.Free;
end;

procedure TestNullableRttiLinux.TestReadNullAbleStringByRtti;
var
  LRttiProp: TRttiProperty;
  LRttiType: TRttiType;
  LValue: TNullableString;
  LTValue: TValue;
const
  __READVALUE = 'TestReadValue';
begin
  LRttiType := TType.GetType<TTestClass>;
  LRttiProp := LRttiType.GetProperty('NullableStringField');
  FTestClass.NullableStringField := __READVALUE;
  LTValue := LRttiProp.GetValue(FTestClass);
  LValue := LTValue.ToType<TNullableString>;
  Assert.AreEqual(True, LValue.Value.Equals(__READVALUE));
end;

procedure TestNullableRttiLinux.TestWriteNullAbleStringByRtti;
var
  LRttiProp: TRttiProperty;
  LRttiType: TRttiType;
  LValue: TNullableString;
  LSValue: string;
const
  __WRITEVALUE = 'TestWriteValue';
begin
  LRttiType := TType.GetType<TTestClass>;
  LRttiProp := LRttiType.GetProperty('NullableStringField');
  LValue := __WRITEVALUE;
  LRttiProp.SetValue(FTestClass, TValue.From<TNullableString>(LValue));
  LSValue := FTestClass.NullableStringField;
  Assert.AreEqual(True, LSValue.Equals(__WRITEVALUE));
end;

{ TestNullableRttiLinux.TTestClass }

function TestNullableRttiLinux.TTestClass.GetNullableStringField: TNullableString;
begin
  Result := FNullAbleStringField; //<=== AV when RTTI GetValue. Self = nil;
end;

procedure TestNullableRttiLinux.TTestClass.SetNullableStringField(const Value: TNullableString);
begin
  FNullAbleStringField := Value;
end;

initialization
  TDUnitX.RegisterTestFixture(TestNullableRttiLinux);
end.

Comments (2)

  1. Inkvizi reporter

    Thank you. I stop research when saw that unmanaged types was work fine and made wrong conclusions becouse record types we used only from spring4d. Will wait fix from Embarcadero.

  2. Log in to comment