The object contains entries for all its fields, as well as additional space for storing a pointer to a table of virtual methods. VMT contains more than just virtual method pointers. I explain more about VMT on my website, including the diagram.
Delphi 2009 apparently introduces another hidden field in addition to the VMT pointer for storing the synchronization monitor. You can determine if it is added at the beginning or at the end of the class using simple code:
type TTest = class FField: Integer; end; var obj: TTest; ObjAddr, FieldAddr: Cardinal; begin Assert(TTest.InstanceSize = 12); obj := TTest.Create; ObjAddr := Cardinal(obj); FieldAddr := Cardinal(@(obj.FField)); writeln(FieldAddr - ObjAddr); end.
If it prints the value 4, then the monitor field should be at the end of the object, because 4 only considers the size of the VMT pointer. If it prints the value 8, then the monitor field should be at the beginning, next to the VMT pointer.
I expect you to find the monitor at the beginning. Otherwise, this means that the layout of the descendant object is not just the layout of the base object with all the new fields added. This would mean that the offset of the monitor field depends on the type of runtime of the object, which complicates the implementation.
When a class implements an interface, the object layout includes more hidden fields. Fields contain pointers to the reference value of the object interface. When you have an IUnknown reference to an object, the pointer that it contains does not match the pointer to the VMT field of the object, which is what you have with a normal object reference. The value of the IUnknown pointer will be the address of the hidden field. I wrote more about the layout of classes that implement interfaces .
Rob kennedy
source share