Различия в представлении данных разных версий Делфи
От: Whistler Россия Блог на GotDotNet.ru
Дата: 04.12.04 18:00
Оценка:
В базе данных хранятся записи, они были много времени назад добавлены прогой, написанной на старой 2, 3, 4 Делфи... (не первой — прога 32-бит)

Дык вот,
один из типов полей в базе 'image' и туда прога сохраняла переменную типа запись

  TOldAnswerType = (atNumeric, atNumericSet, atText, atUnknown);

  TOldAnswer = record
    case aType: TOldAnswerType of
      atNumeric: (nNumeric: Extended; nPrecis: Byte);
      atNumericSet: (nsNumerics: array[0..15] of Extended;
                     nsPrecis: array[0..15] of Byte; nsCount: Byte;
                     nsNoSort: Boolean);
      atText: (tText: string[255]; tNoCase: Boolean);
      atUnknown: (uReserved: Integer);
  end;


теперь в наше время пишу прогу (на Delphi 2005, на 7ой тоже пробовал — тоже самое), которая б это поле прочитала, при чтении из базы в эту record сохраняется полнейшая муть, к тому же в базе поле с record занимает 260 байт, а размер моего record 264 байта...

описание record'а — точь в точь вырезано со старого исходника...
что изменилось на протяжении версий?

*я б проексперементировал бы, тока у меня сейчас нет старой Delphi...*

Заранее спасибо!
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re: Различия в представлении данных разных версий Делфи
От: Shadowspan Россия  
Дата: 04.12.04 18:57
Оценка:
Здравствуйте, Whistler, Вы писали:


W>  TOldAnswer = packed record


попробуй с packet, может помочь
... << RSDN@Home 1.1.3 stable >>
Re[2]: Различия в представлении данных разных версий Делфи
От: Whistler Россия Блог на GotDotNet.ru
Дата: 04.12.04 19:18
Оценка:
Здравствуйте, Shadowspan, Вы писали:

S>Здравствуйте, Whistler, Вы писали:


S>

W>>  TOldAnswer = packed record

S>


S>попробуй с packet, может помочь


не бестолку, ... она стала 258 весить байт, а надо 260, а ни где нельзя почитать про внутреннее представление этих record"ов с условием?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[3]: Различия в представлении данных разных версий Делфи
От: Anatoly Podgoretsky Эстония http://www.podgoretsky.com
Дата: 05.12.04 09:25
Оценка: +1
Здравствуйте, Whistler, Вы писали:

W>Здравствуйте, Shadowspan, Вы писали:


S>>Здравствуйте, Whistler, Вы писали:


S>>

W>>>  TOldAnswer = packed record

S>>


S>>попробуй с packet, может помочь


W>не бестолку, ... она стала 258 весить байт, а надо 260, а ни где нельзя почитать про внутреннее представление этих record"ов с условием?


Об этом надо было думать раньше, а сейчас придется разбираться с выравниванием отдельных частей и при необходимости вставлять псевдоэелементы в структуру, чтобы все составляющие оказались на своих местах или играть с параметрами выравнивания, что не избавит от анализа результатов.
Re[4]: Различия в представлении данных разных версий Делфи
От: Sergei I. Gorelkin Россия  
Дата: 05.12.04 10:30
Оценка:
Здравствуйте, Anatoly Podgoretsky, Вы писали:

AP>Здравствуйте, Whistler, Вы писали:


W>>Здравствуйте, Shadowspan, Вы писали:


S>>>Здравствуйте, Whistler, Вы писали:


<skipped>

Что тут можно сказать... Самый длинный вариант этой записи — это случай atText. Поле tText занимает 256 байт (255 байт строки плюс один байт длины, т.к. ShortString). Поле tNoCase — еще один байт. Итого 257. Округлив до значения, кратного 4, получаем 260.
Поскольку с Delphi7 получается либо 264 (если не packed), либо 258 (если packed), то напрашивается предположение о том, что он добавляет еще один байт. Возможно, как раз значение OldAnswerType. И смысл в этом есть, потому что в такой записи, не зная заранее этого OldAnswerType, очень трудно понять, какой из вариантов записан. Надо полагать, что программа его читает из какого-то другого поля базы.
Возможное решение: вместо TOldAnswer применить отдельные типы:

TOldAnswer1=record
  nNumeric: Extended;
  nPrecis: Byte;
  Padding: array[0..(259-sizeof(Extended)-sizeof(Byte))] of byte;
end;

TOldAnswer2=record
  nsNumerics: array[0..15] of Extended;
  nsPrecis: array[0..15] of Byte;
  nsCount: Byte;
  nsNoSort: Boolean;
  Padding: array[0..(259-16*sizeof(Extended)-18*sizeof(Byte))] of byte;
end;

TOldAnswer3=record
  tText: string[255];
  tNoCase: boolean;
  // тут padding не нужен
end;


И далее приводить типы по мере надобности.
Размер всех должен быть 260 байт, если я ничего не напутал с Padding. Если это будет не так, значит Delphi7 и к "простым" записям что-то добавляет и тут можно попытаться представить запись как набор байт и записывать данные начиная с 4-го...
Re[3]: Различия в представлении данных разных версий Делфи
От: akasoft Россия  
Дата: 05.12.04 11:18
Оценка:
Здравствуйте, Whistler, Вы писали:

W>не бестолку, ...


Могу только посоветовать откомпилировать (rebuild) программу с выключенной оптимизацией и/или поиграться настройкой Record field alignment у Compiler. Но это всё танцы с бубуном, так что тут я согласен с Анатолием.
... << RSDN@Home 1.1.4 beta 3 rev. 244 Goran Bregovic — Tale III (lento Arabesco) >>
Re[4]: Различия в представлении данных разных версий Делфи
От: Anatoly Podgoretsky Эстония http://www.podgoretsky.com
Дата: 05.12.04 11:43
Оценка:
Здравствуйте, akasoft, Вы писали:

A>Здравствуйте, Whistler, Вы писали:


W>>не бестолку, ...


A>Могу только посоветовать откомпилировать (rebuild) программу с выключенной оптимизацией и/или поиграться настройкой Record field alignment у Compiler. Но это всё танцы с бубуном, так что тут я согласен с Анатолием.


Вроде бы это запись с тегом, тогда в любой записи есть тег, размером наверно в один байт, потом 256 и 1 один байт на последний элемент, итого и выходит 258, а размер 260 говорит об выравнивание на 4 байта.
Если есть старые записи с текстовым типом, то можно просто сделать несколько новых с тем же содержимым, но разным выравниванием и сравнить какой подойдет. Тоже надо повторить и для других тегов.
Re[5]: Различия в представлении данных разных версий Делфи
От: akasoft Россия  
Дата: 05.12.04 14:39
Оценка:
Здравствуйте, Anatoly Podgoretsky, Вы писали:

AP>Вроде бы это запись с тегом, тогда в любой записи есть тег, размером наверно в один байт, потом 256 и 1 один байт на последний элемент, итого и выходит 258, а размер 260 говорит об выравнивание на 4 байта.


Действительно, чего-то не заметил сразу.

Тогда всё проясняется. В D7 любят выравнивать на 8, поэтому там запись стала в 264 байта: 4б на aType, 256б на shortstring tText, 4б на tNoCase.

Для варианта 260 байт есть логичный вариант: 2б на aType, опять 256б на shortstring, 2б на tNoCase. Аналогично, поля в byte/char/boolean выравниваются в 2б.

В общем, математика...
... << RSDN@Home 1.1.4 beta 3 rev. 245 Busta Rhymes — Case Of The P.T.A. >>
Re[3]: Различия в представлении данных разных версий Делфи
От: alive Россия  
Дата: 06.12.04 09:20
Оценка:
Здравствуйте, Whistler, Вы писали:

W>не бестолку, ... она стала 258 весить байт, а надо 260, а ни где нельзя почитать про внутреннее представление этих record"ов с условием?


Не знаю как у старших версий Delphi, но начиная с 5 поменялось выравнивание по умолчанию

The compiler's default data alignment has changed from packed to unpacked for Microsoft compatibility.

Keep yourself alive
Re: Различия в представлении данных разных версий Делфи
От: Whistler Россия Блог на GotDotNet.ru
Дата: 06.12.04 11:29
Оценка: :)
Попутный вопрос:

целые числа хранятся след образом:
(например Word)

15158 => $3B36 => в стеке, диске, памяти как '363B' т.е. все байты идут наоборот, не как людьми записываются
или 16 => $10 => на диске как '1000'; (если не путаю ничего )

а как внутренне хранятся вещественные числа, конкретнее Extented (как он внутренне выглядит, и скока там байт на мантиссу отводится т т.д.)

Пасибо!
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.