[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