Discussion:
[fpc-pascal] Usage of FieldAddress
Ryan Joseph via fpc-pascal
2021-04-04 17:12:43 UTC
Permalink
I'm trying to see fields by name but TObject.FieldAddress doesn't seem to be working. Do I have that correct I should be using FieldAddress to return the pointer of the published property? Some how I can't seem to find an example of FieldAddress on Google....

type
TSomething = class(TPersistent)
private
m_scale: integer;
published
property scale: integer read m_scale write m_scale;
end;


Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.o
Sven Barth via fpc-pascal
2021-04-04 18:10:50 UTC
Permalink
Post by Ryan Joseph via fpc-pascal
I'm trying to see fields by name but TObject.FieldAddress doesn't seem to be working. Do I have that correct I should be using FieldAddress to return the pointer of the published property? Some how I can't seem to find an example of FieldAddress on Google....
type
TSomething = class(TPersistent)
private
m_scale: integer;
published
property scale: integer read m_scale write m_scale;
end;
FieldAddress only works on published fields. Just like MethodAddress
only works on published methods.

For private fields extended RTTI is required which is not yet implemented.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pa
Ryan Joseph via fpc-pascal
2021-04-04 18:15:54 UTC
Permalink
FieldAddress only works on published fields. Just like MethodAddress only works on published methods.
For private fields extended RTTI is required which is not yet implemented.
I don't understand this at all I guess. I thought the properties made them published and I get a "Symbol cannot be published, can be only a class" if I put the field itself in the published section.

Just trying to do this:

PInteger(theClass.FieldAddress('foo'))^ := 10;

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo
Sven Barth via fpc-pascal
2021-04-04 19:07:06 UTC
Permalink
Post by Ryan Joseph via fpc-pascal
FieldAddress only works on published fields. Just like MethodAddress only works on published methods.
For private fields extended RTTI is required which is not yet implemented.
I don't understand this at all I guess. I thought the properties made them published and I get a "Symbol cannot be published, can be only a class" if I put the field itself in the published section.
PInteger(theClass.FieldAddress('foo'))^ := 10;
Only classes or interfaces are supported as published *fields*.

And the visibility of the *property* does not change the visibility of
the *field*, after all the property could be provided by a method.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.fr
Ryan Joseph via fpc-pascal
2021-04-04 20:19:52 UTC
Permalink
Post by Sven Barth via fpc-pascal
Only classes or interfaces are supported as published *fields*.
And the visibility of the *property* does not change the visibility of the *field*, after all the property could be provided by a method.
I know FPC can deserialize JSON with TJSONDeStreamer so maybe I need to use the RTTI functions in TypInfo.pas?

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.f
Sven Barth via fpc-pascal
2021-04-04 20:36:04 UTC
Permalink
Post by Ryan Joseph via fpc-pascal
Post by Sven Barth via fpc-pascal
Only classes or interfaces are supported as published *fields*.
And the visibility of the *property* does not change the visibility of the *field*, after all the property could be provided by a method.
I know FPC can deserialize JSON with TJSONDeStreamer so maybe I need to use the RTTI functions in TypInfo.pas?
The RTTI streaming relies on *published properties* (and published
methods for the event handlers).

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/cgi
Ryan Joseph via fpc-pascal
2021-04-04 20:49:07 UTC
Permalink
The RTTI streaming relies on *published properties* (and published methods for the event handlers).
Sorry Sven, I'm not understand what I'm doing wrong. From original example "scale" is a published property right? So FieldAddress only works on published fields, which are not supported unless they are classes/interfaces.

type
TSomething = class(TPersistent)
private
m_scale: integer;
published
property scale: integer read m_scale write m_scale;
end;

I have used published properties like this for JSON streaming, i.e.:

type
TVectorObject = class(TPersistent)
private
components: array[0..2] of integer;
published
property x: integer read components[0] write components[0];
property y: integer read components[1] write components[1];
property z: integer read components[2] write components[2];
end;

which works just fine so I assume I can use the RTTI functions, just not FieldAddress.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freep
Sven Barth via fpc-pascal
2021-04-05 07:17:20 UTC
Permalink
Post by Sven Barth via fpc-pascal
On Apr 4, 2021, at 2:36 PM, Sven Barth via fpc-pascal <
The RTTI streaming relies on *published properties* (and published
methods for the event handlers).
Sorry Sven, I'm not understand what I'm doing wrong. From original example
"scale" is a published property right? So FieldAddress only works on
published fields, which are not supported unless they are
classes/interfaces.
type
TSomething = class(TPersistent)
private
m_scale: integer;
published
property scale: integer read m_scale write m_scale;
end;
type
TVectorObject = class(TPersistent)
private
components: array[0..2] of integer;
published
property x: integer read components[0] write components[0];
property y: integer read components[1] write components[1];
property z: integer read components[2] write components[2];
end;
which works just fine so I assume I can use the RTTI functions, just not FieldAddress.
Correct. You need to use GetOrdProp and similar from the TypInfo unit or
the object oriented variant from the Rtti unit.

Note: you don't need to inherit from TPersistent if you simply want to
manually access such properties, setting $M+ before the type (and resetting
it afterwards) is enough to enable the published section.

Regards,
Sven
Loading...