Why does TValue.Make require a pointer to an object reference?

I always had the impression that the objects in Delphi actually refer to memory cells, which, in turn, I thought were saved as pointer variables.

Now I want to make a TValue from an object. Consider this:

TValue.Make(AObject, TypeInfo(TMyObject), val); 

where val: TValue . This will not work. In fact, subsequent use of val will result in an access violation. However, if we use the operator address, for example:

 TValue.Make(@AObject, TypeInfo(TMyObject), val); 

things are good. This was unexpected for me, as I thought that AObject was (under the hood) actually a pointer. Am I mistaken or is this a fad using the TValue.Make method? Can someone please enlighten me?

+8
object pointers delphi
source share
3 answers
 procedure Foo; var I: Integer; // value type O: TObject; // reference type begin @I; // Get a pointer to I O := TObject.Create; @O; // Get a pointer to the memory "behind" the reference O end; 
  • The @I location as well as the O location (link) is on the stack.
  • The location of @O, on the other hand, is on the heap.

This usually doesn't matter much because the compiler knows when to look up and when not to.

In the case of TValue.Make function takes a pointer.

  • When you specify Make(O... , the compiler will rigidly bind the link to a pointer (which points to the stack).
  • When you specify Make(@O... , the compiler will first be fuzzy and then create a pointer to a location on the heap.

So, you should give the compiler a hint in this case, because it does not know what type of pointer TValue.Make expects.

+9
source share

The ABuffer argument that you pass to TValue.Make is a pointer to the value that you want to store in TValue. It does not matter if the type itself is a pointer or not. Therefore, you need to pass a reference to AObject, even if the AObject itself is also a pointer.

In the above example, I would rather use the TValue.From <T> Method:

 val := TValue.From<TMyObject>(AObject); 

If the info type is not known in compiletime, you should use TValue.Make - otherwise TValue.From <T> is easier to use.

+2
source share

In your example, AObject is a reference to the object, not the object itself. This is a way to declare a reference to an object in Delphi, and not to another language, where you must explicitly add a refrence or pointer to the object.

So AObject or @AObject should work the same way in your case, but like TValue.Make() to take a pointer to the buffer in the first parameter, you must specify Addr(AObject) or @AObject to the function.

+1
source share

All Articles