Динамические структуры
Спасибо!
Пусть имеем фиксированную часть
TFixRec = object
__a: type1;
__b: type2;
__c: type3;
end;
и нам надо в зависимости от "чего-то там" дописать либо не дописывать в конец этой записи какую-то инфу (динамическая часть). Надеюсь, постановку задачи я понял правильно %)
Делается динамика так (по крайней мере, так сделано в WinAPI, а посему не исключена оптимизация ;)).
Пусть полное (максимально возможное) содержание динамической части представляется как
TDynRec = object
__dyn1: SomeType;
__dyn2: AnotherType;
end;
Тогда надо добавить по паре полей на каждое поле из DynRec:
TDynRecData = object(TFixRec)
__dyn1Offset: word;{если размер выделяемой памяти ограничен сегментом (64 kb); иначе можно longint - по максимуму}
__dyn1Size: word;{те же соображения}
__dyn2Offset: word;
__dyn2Size: word;
end;
причем dyn1Size := sizeof(SomeType), dyn2Size := sizeof(AnotherType), etc.
То есть фактический размер фиксированной части получается равным sizeof(TDynRecData). Итоговая структура (фиксированная и динамическая части) PDynStruct будет иметь размер sizeof(TDynRecData) + размер той части TDynRec, которую мы хотим засунуть в нашу, полностью динамическую, итоговую структуру. Теперь
PDynStruct: pointer;
DynRec: TDynRec;
DynRecData: TDynRecData;
GetMem(PDynStruct, sizeof(DynStructSize));{DynStructSize - размер итоговой структуры}
DynRecData.a := ...;
DynRecData.b := ...;
DynRecData.c := ...;
{Код ниже нужен только для тех данных из TDynRec, которым суждено попасть в TDynStruct}
DynRecData.dyn1Size := sizeof(SomeType);
DynRecData.dyn1Offset := sizeof(TDynRecData);
DynRecData.dyn2Size := sizeof(AnotherType);
DynRecData.dyn2Offset := DynRecData.dyn1Offset + DynRecData.dyn1Size;
{Для данных, не попадающих в TDynStruct:}
DynRecData.dyn1Size := 0;
DynRecData.dyn2Size := 0;
{Пусть имеем процедуру побайтного копирования блоков памяти CopyBytes(source, dest, count), где source - указатель на источник, dest - указатель на приемник, count - количество пересылаемых из источника в приемник байт.}
CopyBytes(@DynRecData, PDynStruct, sizeof(DynRecData));
{Для всех, входящих в PDynStruct, данных динамической части:}
CopyBytes(addr(DynRec.dyn1), PDynStruct + DynRecData.dyn1Offset, DynRecData.dyn1Size);
CopyBytes(addr(DynRec.dyn2), PDynStruct + DynRecData.dyn2Offset, DynRecData.dyn2Size);
Вот тебе методика. Для чтения данных берешь по соответствующим смещениям относительно начала PDynStruct набор байтов размером dynSize и приводишь к нужному типу.