[fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

Graeme Geldenhuys graemeg.lists at gmail.com
Tue Nov 20 14:07:29 CET 2007


Hi,

I've included a program that shows the problem. I'm using FPC 2.2.0
under Linux on a Intel P4.
I've got a function PropertyMatch() which returns true or false if a
given property matches a specified value. All very simple.
But for some strange reason TypInfo.GetPropValue returns a boolean
which seems to test ok using VarIsType(), but if I cast it as a
boolean variant using VarIsType() just to be sure, the application
throws the error show below.

Any ideas how to resolve this issue?  Is it a FPC bug?  This same code
works perfectly with Delphi 7-2007.


graemeg at graemeg:rtti_bug$ ./project1
Test 1 passed. Integer property matched.
Test 2 passed. String property matched.
An unhandled exception occurred at $0807F54D :
EVariantTypeCastError : Could not convert variant of type (Int64) into
type (Boolean)
  $0807F54D
  $0807C5EB
  $0807D139
  $08048467  main,  line 85 of project1.lpr



----[  Backtrace  ]------------------------------
(gdb) break fpc_raiseexception
Breakpoint 1 at 0x8054886
(gdb) run
Starting program: /home/graemeg/programming/tests/rtti_bug/project1
Test 1 passed. Integer property matched.
Test 2 passed. String property matched.

Breakpoint 1, 0x08054886 in fpc_raiseexception ()
(gdb) bt
#0  0x08054886 in fpc_raiseexception ()
#1  0x0807f539 in VARIANTS_VARCASTERROR$WORD$WORD ()
#2  0x0807c5cb in VARIANTS_SYSVARCAST$VARIANT$VARIANT$LONGINT ()
#3  0x0807d119 in VARIANTS_VARASTYPE$VARIANT$WORD$$VARIANT ()
#4  0xbfa82934 in ?? ()
#5  0xbfa828d4 in ?? ()
#6  0x08048189 in PROPERTYMATCH (AOBJECT=0xb7f4a100,
PROPNAME=0x80a1ab4, PROPVALUE=void)
    at project1.lpr:41
#7  0x08048467 in main () at project1.lpr:82
-------------  end  ----------------



-----[  the program code  ]------------------------------
program project1;

{$mode objfpc}{$H+}

uses
  Classes, typinfo, variants;


type
  {$M+}
  TMyObject = class(TObject)
  private
    FBoolProp: Boolean;
    FIntProp: Integer;
    FStrProp: string;
  published
    property IntProp: Integer read FIntProp write FIntProp;
    property BoolProp: Boolean read FBoolProp write FBoolProp;
    property StrProp: string read FStrProp write FStrProp;
  end;
  {$M-}


  // This does a test to see if the property PropName's value
  // matches PropValue.
  function PropertyMatch(AObject: TObject; PropName: string;
        PropValue: variant): boolean;
  var
    lSearch, lItem: variant;
    lVarType: TVarType;
    lPropInfo: PPropInfo;
  begin
    lSearch := PropValue;

    lItem := TypInfo.GetPropValue(AObject, PropName);
    lVarType := VarType(lItem);

    // Just to be sure that I'm comparing the SAME kind of values
    if VarIsType(PropValue, varBoolean) then
    begin
      lItem := VarAsType(lItem, varBoolean);  // <<=== EVariantTypeCastError
//      lItem := VarAsType(True, varBoolean);  // this passes if we
force boolean
    end
    else
    begin
      lSearch := VarAsType(lSearch, lVarType);
      lItem := VarAsType(lItem, lVarType);
    end;

    result := (lSearch = lItem);
  end;


var
  obj: TMyObject;
  lBool: Boolean;
begin
  obj := TMyObject.Create;
  try
    obj.IntProp   := 123;
    obj.BoolProp  := True;
    obj.StrProp   := 'abcd';


    // Testing a Integer property
    if PropertyMatch(obj, 'IntProp', 123) then
      writeln('Test 1 passed. Integer property matched.')
    else
      writeln('Test 1 failed');


    // Testing a String property
    if PropertyMatch(obj, 'StrProp', 'abcd') then
      writeln('Test 2 passed. String property matched.')
    else
      writeln('Test 2 failed');


    // Testing a Boolean property
    // We can also try it with a typed variable
//    lBool := True;
//    if PropertyMatch(obj, 'BoolProp', lBool) then
    if PropertyMatch(obj, 'BoolProp', True) then
      writeln('Test 3 passed. Boolean property matched.')
    else
      writeln('Test 3 failed');

  finally
    obj.Free;
  end;
end.

-------------  end  ----------------


Regards,
  - Graeme -


_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/



More information about the fpc-devel mailing list