Board index » delphi » RTTI - GetPropValue doesn't work with interfaces?

RTTI - GetPropValue doesn't work with interfaces?


2007-05-31 03:21:17 AM
delphi96
I have this interface:
ITest = interface(IInvokable)
['{33AA7F6C-5C03-4C51-ADF3-0EC0E7188429}']
function GetName: string;
procedure SetName(const Value: string);
property Name: string read GetName write SetName;
end;
And this class:
{$M+}
TTest = class(TInterfacedObject, ITest)
private
FName: string;
function GetName: string;
procedure SetName(const Value: string);
published
property Name: string read GetName write SetName;
end;
{$M-}
I'm creating a TTest object on this way:
var
Test: ITest; //<--- Interface type
...
Test := TTest.Create; //<--- Class type
Test.Name := 'abcde';
Now, I have to get Test's properties using GetPropValue. By the way, it
doesn't accept interface types:
GetPropValue(Test, 'Name'); //<--- Doesn't compile
And I can not doing typecasts, because it causes access violation:
GetPropValue(TTest(Test), 'Name'); //<--- Causes an access violation
So, what's the correct form to doing this?
Thanks.
 
 

Re:RTTI - GetPropValue doesn't work with interfaces?

"Diogo Augusto Pereira" wrote
Quote

Now, I have to get Test's properties using GetPropValue. By the way, it
doesn't accept interface types:
No, RTTI isn't designed to be used with interfaces. Why can not you just add
the value to the interface?
Quote
So, what's the correct form to doing this?
Don't know that there is a correct way--it's not clear what you're trying to
accomplish by wrapping RTTI access (which is inherently not type-specific)
in an interface (which also tends to abstract the implementing type).
However, if you really have to use RTTI on an interface reference, the
easiest way would be to add an Instance : TObject member to the interface
and have classes implement it as Instance := self.
bobD
 

Re:RTTI - GetPropValue doesn't work with interfaces?

Diogo Augusto Pereira <XXXX@XXXXX.COM>wrote in news:465dcf46$1
@newsgroups.borland.com:
Quote
So, what's the correct form to doing this?
If anyone can explain it, Hallvard can. Read through the articles returned
found in the link below.
hallvards.blogspot.com/search
 

Re:RTTI - GetPropValue doesn't work with interfaces?

Bob Dawson escreveu em 30/5/2007 16:53:
Quote
"Diogo Augusto Pereira" wrote
>Now, I have to get Test's properties using GetPropValue. By the way, it
>doesn't accept interface types:

No, RTTI isn't designed to be used with interfaces. Why can not you just add
the value to the interface?

>So, what's the correct form to doing this?

Don't know that there is a correct way--it's not clear what you're trying to
accomplish by wrapping RTTI access (which is inherently not type-specific)
in an interface (which also tends to abstract the implementing type).

However, if you really have to use RTTI on an interface reference, the
easiest way would be to add an Instance : TObject member to the interface
and have classes implement it as Instance := self.

bobD


I want to use RTTI because the interface will have a lot of fields and I
need to copy their data into report's components, which will have the
same fields.
Using Instance field works fine, but now I have getting problems with
values returned by RTTI functions. If a variant property will be filled
with TDateTime value, and if I get this value with RTTI, it will be
considered a Double value... ):
So, I will use the interface fields directly.
Thanks.
 

Re:RTTI - GetPropValue doesn't work with interfaces?

Diogo Augusto Pereira a écrit :
Quote
I want to use RTTI because the interface will have a lot of fields and I
need to copy their data into report's components, which will have the
same fields.
Interfaces don't have fields, only properties, they don't have any
storage which may be why RTTI cannot do anything with them; .NET
reflection can do this but that would mean leaving Win32 behind :-(
Quote
Using Instance field works fine, but now I have getting problems with
values returned by RTTI functions. If a variant property will be filled
with TDateTime value, and if I get this value with RTTI, it will be
considered a Double value... ):
The RTTI will actually tell you if the value is really a date, I can't
remember how at the moment but the TypeInfo is there if you look.
Joanna
--
Joanna Carter [TeamB]
Consultant Software Engineer
 

Re:RTTI - GetPropValue doesn't work with interfaces?

"Diogo Augusto Pereira" wrote
Quote

Using Instance field works fine, but now I have getting problems with
values returned by RTTI functions. If a variant property will be filled
with TDateTime value, and if I get this value with RTTI, it will be
considered a Double value... ):
Yes, RTTI doesn't know the difference between float and TDateTime, so that's
something you have to work around.
You can do something like interrogating the PropTypeName to see if it
contains 'DateTime', and if it does, then transfer the value as a TDateTime
rather than as a variant. Of course that means you have to have a strict
convention that any special datetime type you use has to preserve the naming
'DateTime' convention.
bobD
 

Re:RTTI - GetPropValue doesn't work with interfaces?

"Joanna Carter [TeamB]" wrote
Quote

The RTTI will actually tell you if the value is really a date, I can't
remember how at the moment but the TypeInfo is there if you look.
Actually it is not (at least as of D2006) --the TTypeKind enum doesn't
include a datetime type--just a float. it is not within the TFloatType enum
as a subtype either.
As I indicated in my other post, you can figure it out by convention by
looking at the PropInfo.PropType.Name.
bobD
 

Re:RTTI - GetPropValue doesn't work with interfaces?

Joanna Carter [TeamB] escreveu em 31/5/2007 14:59:
Quote

Interfaces don't have fields, only properties, they don't have any
storage which may be why RTTI cannot do anything with them; .NET
reflection can do this but that would mean leaving Win32 behind :-(
In fact, I was talking about properties. Unfortunately, leaving Win32
behind is not so easy... ):
Quote
The RTTI will actually tell you if the value is really a date, I can't
remember how at the moment but the TypeInfo is there if you look.

 

Re:RTTI - GetPropValue doesn't work with interfaces?

Bob Dawson escreveu em 31/5/2007 15:56:
Quote

As I indicated in my other post, you can figure it out by convention by
looking at the PropInfo.PropType.Name.
I will try this. But, what I was trying to simplify is going to be more
complex!
 

Re:RTTI - GetPropValue doesn't work with interfaces?

"Diogo Augusto Pereira" wrote
Quote

I will try this. But, what I was trying to simplify is going to be more
complex!
You have to remember that TypInfo was developed primarily for the use of the
IDE and component makers--as far as I know, it has never been officially
documented for 'routine' use.
bobD
 

Re:RTTI - GetPropValue doesn't work with interfaces?

begin
//I want to use RTTI because the interface will have a lot of fields
//and I need to copy their data into report's components, which will
//have the same fields.
//
//Using Instance field works fine, but now I have getting problems with
//values returned by RTTI functions. If a variant property will be
//filled with TDateTime value, and if I get this value with RTTI, it
//will be considered a Double value... ):
//
//So, I will use the interface fields directly.
end;
Diogo Augusto Pereira ,
To work with app framework and interface, I think that is more easy to
implement something like RTTI does, and use metadata to fill all needs.
I made that in Jazz Framework.
--
[]s
Cesar Romero
 

Re:RTTI - GetPropValue doesn't work with interfaces?

Quote
Now, I have to get Test's properties using GetPropValue. By the way, it
doesn't accept interface types:
GetPropValue(Test, 'Name'); //<--- Doesn't compile
And I can not doing typecasts, because it causes access violation:
GetPropValue(TTest(Test), 'Name'); //<--- Causes an access violation
Diogo, with use of InfraReflection framework you will can do in Delphi
win32 almost all that .Net ou Java Reflection can do.
 

Re:RTTI - GetPropValue doesn't work with interfaces?

Bob Dawson writes:
Quote
"Diogo Augusto Pereira" wrote
>
>Using Instance field works fine, but now I have getting problems with
>values returned by RTTI functions. If a variant property will be
>filled with TDateTime value, and if I get this value with RTTI, it
>will be considered a Double value... ):

Yes, RTTI doesn't know the difference between float and TDateTime, so
that's something you have to work around.

You can do something like interrogating the PropTypeName to see if it
contains 'DateTime', and if it does, then transfer the value as a
TDateTime rather than as a variant. Of course that means you have to
have a strict convention that any special datetime type you use has
to preserve the naming 'DateTime' convention.

bobD
Bob,
That was a hack I used to apply, but now this code will do the job just
as well without the need for naming compromises :-
Function GetDataType(pObject : TObject; Const pProperty : String) :
TDatatype;
Var
PropertyPtr : PPropInfo;
lDateTest : PPropInfo;
lDateInfo : Pointer;
Function PropertyKind(pObject : TObject; Const pProperty : String) :
TTypeKind;
Begin
Result := tkUnknown; //default
{ Get reference to property info.. }
PropertyPtr := GetPropInfo(pObject.ClassInfo, pProperty);
If (PropertyPtr <>Nil) Then //return property type
Result := PropertyPtr^.PropType^.Kind;
End;
Begin
Result := dtNotknown;
Case PropertyKind(pObject, pProperty) Of
tkClass,
tkString,
tkLString,
tkWString,
tkEnumeration : Result := dtString;
tkInt64,
tkInteger : Result := dtInteger;
tkChar : Result := dtChar;
tkFloat :
Begin
If (GetTypeData(PropertyPtr.PropType^)^.FloatType = ftCurr) Then
Result := dtCurrency
Else
Begin
lDateInfo := TypeInfo(TDateTime);
lDateTest := GetPropInfo(pObject, pProperty);
If (lDateInfo = lDateTest^.PropType^) Then
Result := dtDateTime
Else
Result := dtExtended;
End;
End;
End; { Case }
End;
Cheers,
Andy
--
 

Re:RTTI - GetPropValue doesn't work with interfaces?

"Andrew Denton" wrote
Quote

That was a hack I used to apply,
No question it is a hack ...
Quote
but now this code will do the job just
as well without the need for naming compromises :-
Not really--it just imposes a different constraint. The line
Quote
If (lDateInfo = lDateTest^.PropType^) Then
tests whether the property exactly equals a TDateTime, and so misses
RTTI-enabled derived types. Try it with a property of this type
type
TNewDateTime = type TDateTime;
and you will see what I mean--it returns dtextended.
bobD
 

Re:RTTI - GetPropValue doesn't work with interfaces?

That's true, but it is a neater solution than checking the property name
and realistically, there's little need to derive a type from TDateTime
anyway.
Bob Dawson writes:
Quote
Not really--it just imposes a different constraint. The line

>If (lDateInfo = lDateTest^.PropType^) Then

tests whether the property exactly equals a TDateTime, and so misses
RTTI-enabled derived types. Try it with a property of this type

type
TNewDateTime = type TDateTime;

and you will see what I mean--it returns dtextended.

bobD
--