Delphi - TValue for pointer and back
I am struggling with a simple piece of code and even this is simple, I cannot find a solution for this. Partly I have an event called so
OnReadMessageParameter(Self, aName, aTypeInfo, pointer(@aValue), [psIsTValue]);
The important parameter is aValue, which is of type TValue . When it's called aValue.IsObject it's true. I assigned my procedure to this event in order to process data from it:
.DoOnReadMessageParameter(Sender: TROMessage; const aName: string;
aTypeInfo: PTypeInfo; const DataRef: pointer; Attributes: TParamAttributes);
Now what is my problem, I tried several ways to convert the DataRef to a TValue element:
var val: tvalue;
tvalue.Make(@DataRef^,TypeInfo(TValue),val);
or another attempt
val := TValue(@DataRef^);
but the IsObject property is false. It must be something really simple that I am missing. Any idea?
source to share
If aValue is a TValue, @aValue is a pointer to the TValue structure, not the value it wraps. A better option would be to make the OnReadMessageParameter event its own DataRef, typical of the TValue itself, rather than an untyped pointer.
However, if you cannot control this, you need to cast the DataRef to the pointer to TValue and then read it -
type
PValue = ^TValue;
var
val: TValue;
begin
val := PValue(DataRef)^;
source to share
If you can't manage DoOnReadMessageParameter
, but you know you DataRef
will always be a pointer to TValue
, then:
type
PValue = ^TValue;
procedure [someclass].DoOnReadMessageParameter(Sender: TROMessage; const aName: string;
aTypeInfo: PTypeInfo; const DataRef : pointer; Attributes: TParamAttributes);
var
HaveObject : boolean;
begin
HaveObject := PValue(DataRef).IsObject;
//...
end;
Assuming you are in control DoOnReadMessageParameter
and not the event OnReadMessageParameter
:
type
PValue = ^TValue;
procedure [someclass].DoOnReadMessageParameter(Sender: TROMessage; const aName: string;
aTypeInfo: PTypeInfo; const DataRef : PValue; Attributes: TParamAttributes);
var
HaveObject : boolean;
begin
HaveObject := DataRef.IsObject;
//...
end;
If you have control over both:
OnReadMessageParameter(Self, aName, aTypeInfo, aValue, [psIsTValue]);
procedure [someclass].DoOnReadMessageParameter(Sender: TROMessage; const aName: string;
aTypeInfo: PTypeInfo; const DataRef : TValue; Attributes: TParamAttributes);
Finally, if it DataRef
can point to anything, you're out of luck since you don't have type information with which to create TValue instances.
source to share