The following code:
---------------------------------------------------------
Unit
        RTTIObject;

Interface

Uses
        Classes,
        SysUtils,
        StrUtils,
        Contnrs,
        TypInfo;

Type
 TRTTIObject = Class(TObject)
        Private
                fInstanceName: String;
  fTypeData: PTypeData;
  fPropList: PPropList;
  fNumProperties: Integer;
        Protected
                Procedure SetProperty(Const aName, aValue: String); Overload;
                Function GetProperty(Const aName: String): String; Overload;
                Procedure SetProperty(Const aIndex: Integer; aValue: String); 
Overload;
                Function GetProperty(Const aIndex: Integer): String; Overload;
                Function GetPropertyName(Const aIndex: Integer): String;
                Function GetPropertyType(Const aIndex: Integer): String;
                Function GetPropertyIndex(Const aName: String): Integer;
        Public
                Constructor Create(Const aInstanceName: String); Virtual;
                Destructor Destroy; Override;
                Property Properties[aName: String]: String Read GetProperty 
Write SetProperty;
                Property Properties[aIndex: Integer]: String Read GetProperty 
Write
SetProperty;
                Property PropertyCount: Integer Read fNumProperties;
        Published
                Property InstanceName: String Read fInstanceName;
        End;
        
Implementation

Procedure TRTTIObject.SetProperty(Const aName, aValue: String);
Var
  lRow : Integer;
Begin
        lRow := GetPropertyIndex(aName);
        SetProperty(lRow, aValue);
End;

Function TRTTIObject.GetProperty(Const aName: String): String;
Var
  lRow : Integer;
 Begin
        lRow := GetPropertyIndex(aName);
        Result := GetProperty(lRow);
End;

Procedure TRTTIObject.SetProperty(Const aIndex: Integer; aValue: String);
Var
        lName: String;
Begin
 lName := fPropList^[aIndex]^.Name;
        Case fPropList^[aIndex]^.PropType^.Kind Of
                tkInteger : SetOrdProp(Self, lName, StrToInt(aValue));
                tkFloat   : If fPropList^[aIndex]^.PropType^.Name = 'TDateTime' 
Then
                                                                                
                                        SetFloatProp(Self, lName, 
StrToDateTime(aValue))
                                                                                
                                Else
                                                                                
                                        SetFloatProp(Self, lName, 
StrToFloat(aValue));
                tkSString : SetStrProp(Self, lName, aValue);
                tkLString : SetStrProp(Self, lName, aValue);
                tkAString : SetStrProp(Self, lName, aValue);
                tkWString : SetStrProp(Self, lName, aValue);
                tkVariant : SetVariantProp(Self, lName, aValue);
                tkBool    : SetOrdProp(Self, lName, Ord(LowerCase(aValue) = 
'true'));
                tkInt64   : SetOrdProp(Self, lName, StrToInt(aValue));
                tkQWord   : SetOrdProp(Self, lName, StrToInt(aValue));
                tkUString : SetStrProp(Self, lName, aValue);
        End;
End;

Function TRTTIObject.GetProperty(Const aIndex: Integer): String;
Var
        lName: String;
Begin
        lName := fPropList^[aIndex]^.Name;
        Case fPropList^[aIndex]^.PropType^.Kind Of
                tkInteger : Result := IntToStr(GetOrdProp(Self, lName));
                tkFloat   : If fPropList^[aIndex]^.PropType^.Name = 'TDateTime' 
Then
                                                                                
                                        Result := 
DateTimeToStr(GetFloatProp(Self, lName))
                                                                                
                                Else
                                                                                
                                        Result := FloatToStr(GetFloatProp(Self, 
lName));
                tkSString : Result := GetStrProp(Self, lName);
                tkLString : Result := GetStrProp(Self, lName);
                tkAString : Result := GetStrProp(Self, lName);
                tkWString : Result := GetStrProp(Self, lName);
                tkVariant : Result := GetVariantProp(Self, lName);
                tkBool    : If Boolean(GetOrdProp(Self, lName)) Then
                                                                                
                                        Result := 'True'
                                                                                
                                Else
                                                                                
                                        Result := 'False';
                tkInt64   : Result := IntToStr(GetOrdProp(Self, lName));
                tkQWord   : Result := IntToStr(GetOrdProp(Self, lName));
                tkUString : Result := GetStrProp(Self, lName);
        End;
End;

Function TRTTIObject.GetPropertyName(Const aIndex: Integer): String;
Begin
        Result := fPropList^[aIndex]^.Name;
End;

Function TRTTIObject.GetPropertyType(Const aIndex: Integer): String;
Begin
        Result := fPropList^[aIndex]^.PropType^.Name;
End;

Function TRTTIObject.GetPropertyIndex(Const aName: String): Integer;
Var
  lRow : Integer;
  lName : String;
Begin
        Result := -1;
        For lRow := 0 To fNumProperties - 1 Do
                        Begin
                                        lName := GetPropertyName(lRow);
                                        If lName = aName Then
                                                        Begin
                                                                        Result 
:= lRow;
                                                                        Break;
                                                        End;
                        End;
End;

Constructor TRTTIObject.Create(Const aInstanceName: String);
Begin
 Inherited Create;
 fInstanceName := aInstanceName;
 fTypeData := GetTypeData(Self.ClassInfo);
 GetMem(fPropList, fTypeData^.PropCount * SizeOf(Pointer));
 fNumProperties := GetPropList(Self.ClassInfo, [ tkInteger, tkFloat,
tkSString, tkLString, tkAString, tkWString, tkVariant, tkBool,
tkInt64, tkQWord, tkUString ], fPropList);
End;

Destructor TRTTIObject.Destroy;
Begin
 FreeMem(fPropList, fTypeData^.PropCount * SizeOf(Pointer));
        Inherited Destroy;
End;

End.
---------------------------------
Uses
        RTTIObject;

Var
        MyRTTIObject : TRTTIObject;

Begin
        MyRTTIObject := TRTTIObject.Create('MyRTTIObject');
        MyRTTIObject.Free;
End.
--------------------------------------


gives strange results...

the compiler issues no warning whatsoever but when i try to run the
compiled test program, it gives this :

---------------------------------
C:\Programacao\testcase>rttiobject-testcase.exe
An unhandled exception occurred at $0040E1E7 :
EAccessViolation : Access violation
  $0040E1E7  TRTTIOBJECT__DESTROY,  line 143 of RTTIObject.pas
  $0040E18A  TRTTIOBJECT__CREATE,  line 139 of RTTIObject.pas
  $00401515  main,  line 8 of rttiobject-testcase.pas
---------------------------------------------------------

looks like the constructor is calling the destructor before doing
anything at all...

what i did wrong ?
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to