Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Динамические структуры

529
19 января 2003 года
tehnic
9 / / 20.12.1999
Народ есть у когнить примеры/исходники с использованием сабжа? Еще хорошо бы какие нибудь учебники.
Спасибо!
463
24 января 2003 года
waterman
178 / / 17.01.2003
Имхо, не сложно написАть самому. Принцип следующий. Есть фиксированная часть структуры (например, record), а есть так называемая динамическая. "Так называемая" она потому, что динамика реализуется искусственно.
Пусть имеем фиксированную часть

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 и приводишь к нужному типу.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог