Discussion:
FPC SetDynArrayProp
(too old to reply)
Ondrej Pokorny
2016-11-28 16:37:32 UTC
Permalink
Raw Message
Hello!

What is the correct way to set a published dynamic array property in
FPC? In Delphi, you use SetDynArrayProp.

Is SetObjectProp safe (packages\fcl-web\src\base\restbase.pp uses this
approach)? See the attached project.

Ondrej
silvioprog
2016-11-28 17:17:39 UTC
Permalink
Raw Message
Post by Ondrej Pokorny
Hello!
What is the correct way to set a published dynamic array property in FPC?
In Delphi, you use SetDynArrayProp.
Is SetObjectProp safe (packages\fcl-web\src\base\restbase.pp uses this
approach)? See the attached project.
Ondrej
It seems a great time to including the
tkDynArray/GetDynArrayProp()/SetDynArrayProp()
to RTL.

Could you open an issue?
--
Silvio Clécio
Ondrej Pokorny
2016-11-28 17:31:37 UTC
Permalink
Raw Message
Is SetObjectProp safe?
OK, no it is not - it doesn't increment the reference count for
properties without a setter:
property Data: TBytes write FBytes;

Ondrej
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
silvioprog
2016-11-28 18:25:37 UTC
Permalink
Raw Message
Is SetObjectProp safe?
OK, no it is not - it doesn't increment the reference count for properties
property Data: TBytes write FBytes;
Ondrej
Yes, and it seems you can't handle properties setting field, eg: "property
Data: TBytes read FData write FData".

An workaround just for testing:

procedure SetDynArrayProp(AInstance: TObject; APropInfo: PPropInfo; const
AValue);
begin
// Caution: it works only with fields! But we can implement the full
version checking methods too, getting some ideas from SetRawInterfaceProp
CopyArray(PPointer(Pointer(AInstance)+PtrUInt(APropInfo^.SetProc)),
@AValue, APropInfo^.PropType, 1);
end;

...
// {$IFDEF FPC}
SetDynArrayProp(O, PropInfo, A);
// {$ELSE}
// SetDynArrayProp(O, PropInfo, A);
// {$ENDIF}
...

Anyway including (Get)SetDynArrayProp() to typinfo solve the problem
because it can check if property's set is a field or a method.
--
Silvio Clécio
silvioprog
2016-11-28 18:46:39 UTC
Permalink
Raw Message
On Mon, Nov 28, 2016 at 3:25 PM, silvioprog <***@gmail.com> wrote:
[...]
Post by silvioprog
Yes, and it seems you can't handle properties setting field, eg: "property
Data: TBytes read FData write FData".
*A workaround just for testing
--
Silvio Clécio
silvioprog
2016-11-28 18:52:39 UTC
Permalink
Raw Message
On Mon, Nov 28, 2016 at 3:25 PM, silvioprog <***@gmail.com> wrote:
[...]
Post by silvioprog
Anyway including (Get)SetDynArrayProp() to typinfo solve the problem
because it can check if property's set is a field or a method.
This version (inspired by FPC's SetRawInterfaceProp()) can handle property
(indexed or not) setting fields or methods:

procedure SetDynArrayProp(AInstance: TObject; APropInfo: PPropInfo; const
AValue: Pointer);
type
TSetPointerProcIndex=procedure(index:longint;const i:Pointer) of object;
TSetPointerProc=procedure(i:Pointer) of object;
var
AMethod: TMethod;
begin
case (APropInfo^.PropProcs shr 2) and 3 of
ptField:
CopyArray(PPointer(Pointer(AInstance)+PtrUInt(APropInfo^.SetProc)),
@AValue, APropInfo^.PropType, 1);
ptStatic,
ptVirtual:
begin
if ((APropInfo^.PropProcs shr 2) and 3)=ptStatic then
AMethod.Code:=APropInfo^.SetProc
else

AMethod.Code:=PCodePointer(Pointer(AInstance.ClassType)+PtrUInt(APropInfo^.SetProc))^;
AMethod.Data:=AInstance;
if ((APropInfo^.PropProcs shr 6) and 1)<>0 then
TSetPointerProcIndex(AMethod)(APropInfo^.Index,AValue)
else
TSetPointerProc(AMethod)(AValue);
end;
end;
end;

It can be a starting for implementing it at typinfo definitively.
--
Silvio Clécio
silvioprog
2016-11-28 19:18:06 UTC
Permalink
Raw Message
On Mon, Nov 28, 2016 at 3:52 PM, silvioprog <***@gmail.com> wrote:
[...]
Post by silvioprog
It can be a starting for implementing it at typinfo definitively.
Done: http://bugs.freepascal.org/view.php?id=31029 .
--
Silvio Clécio
Loading...