Я думаю, что ваша основная проблема связана с тем, что является ссылкой на объект Delphi.Рассмотрим следующий искусственный пример:
type
TMyRecord = record
a, b, c: Integer;
end;
TMyClass = class
a, b, c: Integer;
end;
...
var
MyRecord: TMyRecord;
MyObject: TMyObject;
...
MyObject := TMyObject.Create;
На данный момент у нас есть экземпляры двух, по сути идентичных, структурированных типов.Однако способ, которым Delphi представляет эти экземпляры, совершенно другой.Эта запись называется типом значения, а объект является ссылочным типом.
Когда вы присваиваете переменную ссылочного типа, значение копируется.Например:
MyRecord2.a := 1;
MyRecord1 := MyRecord2;
MyRecord1.a := 2;
Assert(MyRecord1.a<>MyRecord2.a);
Примеры типов значений включают целые числа, перечислимые типы, типы с плавающей запятой, записи, объекты и т. Д.
В отличие от этого, присвоение переменной ссылочного типа копирует ссылку так,что обе переменные ссылаются на один и тот же объект.Например:
MyObject2.a := 1;
MyObject1 := MyObject2;
MyObject1.a := 2;
Assert(MyObject1.a=MyObject2.a);
Одна особенность ссылочных типов состоит в том, что все они распределены в куче, тогда как типы значений могут быть выделены либо в куче, либо в стеке.
Примеры ссылочных типов включают классы, интерфейсы, динамические массивы.
Строки Delphi - забавный гибрид.Хотя они реализованы как ссылки, копирование при записи заставляет их вести себя как типы значений.
Синтаксис Delphi для объектов скрывает тот факт, что они реализованы как ссылки, то есть указатели.
Assert(SizeOf(MyRecord)=3*SizeOf(Integer));//=12
Assert(SizeOf(MyObject)=SizeOf(Pointer));//=4 (or 8 in Delphi 64)
Все это означает, что ваш код слишком сложен.Вам не нужно выделять память для ссылки на объект, поскольку переменная объекта уже является ссылкой.Вы можете написать это так:
//assign object reference to Variant
MyVariant := NativeInt(MyObject);
//extract object reference from Variant
NativeInt(MyObject) := MyVariant;
Обратите внимание, что я использую NativeInt
, так как это целочисленный тип, который определен так, чтобы он был по крайней мере того же размера, что и указатель.Это станет актуальным, когда появится 64-битная версия Delphi.