Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Смещение поля записи в константы / 22 сообщений из 22, страница 1 из 1
25.09.2018, 19:49
    #39707962
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Есть такая запись
Код: pascal
1.
2.
3.
4.
TMyRec = record
  A: Boolean;
  B: Boolean;
end;


Хочу в константах получить смещения полей. Пишу

Код: pascal
1.
2.
3.
4.
5.
type
  PMyRec = ^TMyRec;
const
  PA = @PMyRec(nil).A;
  PB = @PMyRec(nil).B;


PA объявляется. При объявлении PB получаю ошибку[dcc32 Error] E2026 Constant expression expected
Как-то можно извернуться? Ручное вычисление смещения пока не рассматриваю


С уважением, Vasilisk
...
Рейтинг: 0 / 0
25.09.2018, 19:52
    #39707963
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Немного ошибся. В коде так
Код: pascal
1.
2.
  PA = @PMyRec(nil)^.A;
  PB = @PMyRec(nil)^.B;

но ошибка та же
...
Рейтинг: 0 / 0
25.09.2018, 20:04
    #39707966
Гирлионайльдо
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Смешение у такой структуры будет ровна предыдущим элементам.


Что означает, что самый главный адрес указывает на первый элемент A.
Для получения второго элемента NativeUInt(Address) + SizeOf(Boolean) от первого элемента Boolean
...
Рейтинг: 0 / 0
25.09.2018, 20:08
    #39707971
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
ГирлионайльдоСмешение у такой структуры будет ровна предыдущим элементам.+ выравнивание . Именно поэтому_Vasilisk_Ручное вычисление смещения пока не рассматриваю
...
Рейтинг: 0 / 0
25.09.2018, 20:13
    #39707974
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Пока получилось так

Код: pascal
1.
2.
3.
4.
const
  CMyRec: TMyRec = ();
  PA: Pointer = @CMyRec.A;
  PB: Pointer = @CMyRec.B;


Объявление типизированных констант обязательно.

Ну а в коде уже от этих констант отнимаю базовый адрес @CMyRec
...
Рейтинг: 0 / 0
25.09.2018, 20:15
    #39707975
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_Есть такая запись
Код: pascal
1.
2.
3.
4.
TMyRec = record
  A: Boolean;
  B: Boolean;
end;



Хочу в константах получить смещения полей. Пишу

Код: pascal
1.
2.
3.
4.
5.
type
  PMyRec = ^TMyRec;
const
  PA = @PMyRec(nil).A;
  PB = @PMyRec(nil).B;



PA объявляется. При объявлении PB получаю ошибку[dcc32 Error] E2026 Constant expression expected
Как-то можно извернуться? Ручное вычисление смещения пока не рассматриваю
никак, только вручную
...
Рейтинг: 0 / 0
25.09.2018, 22:10
    #39708020
Гирлионайльдо
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_,

Именно у той структуры, которую ты привёл - не будет никакого выравнивания.
Потому как ты не упомянул в ней packed

А ошибка в твоём случае именно потому, что ты у nil данных пытаешься прочитать адреса по смещению (где никак таких данных нет)

Т.е, что бы узнать смещения, а оно как я напомню, начинается от главного адреса, нам надо произвести такой банальный код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  TMyRec = record
    A: Boolean;
    str: string;
    B: Boolean;
    d: Double;
  end;

var
  r: TMyRec;
  BaseAddres: NativeUInt;

procedure printaddr(name: string; p: pointer);
begin
  Writeln(name, ': [', NativeUInt(p), '] ', (NativeUInt(p) - BaseAddres));
end;

begin
  BaseAddres := NativeUInt(@r);
  printaddr('BaseAddres', @r);
  with r do
  begin
    A := false;
    printaddr('A: Boolean', @A);
    str := 'Text 1924';
    printaddr('str: string', @str);
    B := true;
    printaddr('B: Boolean', @B);
    d := 46.46;
    printaddr('d: Double', @d);
  end;
  Readln;

end.



Код: sql
1.
2.
3.
4.
5.
BaseAddres: [4348088] 0
A: Boolean: [4348088] 0
str: string: [4348092] 4
B: Boolean: [4348096] 8
d: Double: [4348104] 16
...
Рейтинг: 0 / 0
25.09.2018, 22:12
    #39708021
Гирлионайльдо
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
А вот у упакованной структуры, смещения будут такие

Код: sql
1.
2.
3.
4.
5.
BaseAddres: [4348088] 0
A: Boolean: [4348088] 0
str: string: [4348089] 1
B: Boolean: [4348093] 5
d: Double: [4348094] 6
...
Рейтинг: 0 / 0
25.09.2018, 22:21
    #39708023
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
ГирлионайльдоА ошибка в твоём случае именно потому, что ты у nil данных пытаешься прочитать адреса по смещению (где никак таких данных нет)
Няшка, жги!!!
...
Рейтинг: 0 / 0
25.09.2018, 22:44
    #39708025
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Гирлионайльдо_Vasilisk_,

Именно у той структуры, которую ты привёл - не будет никакого выравнивания.
Потому как ты не упомянул в ней packed
смещения будут в любом случае, packed или не packed
но ты жги, да
...
Рейтинг: 0 / 0
25.09.2018, 23:43
    #39708054
Gator
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_,

Что так? такая жёсткая экономия памяти? Будет кода больше imho
Сделай integer и работай с маской а не с запясью.
И совместимость и переносимость выше again-imho
...
Рейтинг: 0 / 0
26.09.2018, 06:49
    #39708123
AWSVladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
defecatorГирлионайльдо_Vasilisk_,

Именно у той структуры, которую ты привёл - не будет никакого выравнивания.
Потому как ты не упомянул в ней packed
смещения будут в любом случае, packed или не packed
но ты жги, да

Он про выравнивание, а не про смещение.

Гирлионайльдо, ты прав с точночтью до наоборот.
Отличие record от record packed:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
TRec=record   
  b:byte;
  i:integer
end;
 TRecPack=record packed  
  b:byte;
  i:integer
end;



TRecPack - SizeOf = 5 байт,
TRec - SizeOf = ХЗ байт, как компилятор на душу положит, как раз из-за выравнивания адресов для процессора.
...
Рейтинг: 0 / 0
26.09.2018, 14:54
    #39708511
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
GatorЧто так? такая жёсткая экономия памяти?Нет. Пишу для структуры простенький сериализатор/десериализатор. Не хочется что-то забыть при будущем добавлении полей. А так адреса забил в константный массив и отдаю его сериализатору.

RTTI тут использовать не к месту
...
Рейтинг: 0 / 0
26.09.2018, 15:22
    #39708537
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Для тех, кто любит грабли, мазохизм и прочую экзотику:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
type
  PMyRec = ^TMyRec;
  TMyRec = record
    A: Byte;
    B: Integer;
  end;

const
  PB: Integer = 0; // смещение поля В от начала записи

....

initialization
  PInteger(@PB)^ := Integer(@TMyRec(nil^).B);  
....
...
Рейтинг: 0 / 0
26.09.2018, 15:41
    #39708561
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_Пишу для структуры простенький сериализатор/десериализатор. Не хочется что-то забыть при будущем добавлении полей. А так адреса забил в константный массив и отдаю его сериализатору.

RTTI тут использовать не к месту

Как мне кажется, RTTI именно для таких случаев уместно.
...
Рейтинг: 0 / 0
27.09.2018, 01:00
    #39708936
Gator
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_GatorЧто так? такая жёсткая экономия памяти?Нет. Пишу для структуры простенький сериализатор/десериализатор. Не хочется что-то забыть при будущем добавлении полей. А так адреса забил в константный массив и отдаю его сериализатору.

RTTI тут использовать не к местуМне кажется, тут не RTTI, а оргмеры нужны.
Представь, если не совпадают версии исходной структуры и и вайла со смещениями (описания) структуры.
Ясен пень смещения могут лететь. Даже если поля постоянной длины и есть условия.

В свое время делали разбор тикетов и писали на сях UDF (User Definition Format)
Там исходный тикет содержал бинарные переменной длины поля, флаги, или размеры, версии и прочую мутотень.
UDF (INIфайл по сути - xml тогда не было) содержал описание каждого поля, условия и прочую нужную фигню. Даже COMMENT= был
...
Рейтинг: 0 / 0
27.09.2018, 11:02
    #39709123
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Чтобы не забыть поменять код при добавлении полей, можно использовать такое:
Код: pascal
1.
{$IF Sizeof(TMyRec) <> ExpectedSize}Achtung! Razmeren zapisen nicht sovpadaitung!{$IFEND}


Я такое местами делаю в enum-ах, если на них завязаны какие-то еще данные.
...
Рейтинг: 0 / 0
28.09.2018, 01:14
    #39709596
rtticycle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_Как-то можно извернуться?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
  TFildOffsets = class
    type TOffsets = array of Integer;
    procedure Add(aOffset:Integer; var aOffsets:TOffsets);
    procedure Fild(var aFild:Integer; var aOffsets:TOffsets); overload;
    procedure Fild(var aFild:Double;  var aOffsets:TOffsets); overload;
  end;

  TFilds = class(TFildOffsets)
    A : Integer;
    D : Double;
    class var Offsets:TFildOffsets.TOffsets;
    class constructor Init;
  end;

{ TFildOffsets }

procedure TFildOffsets.Add(aOffset: Integer; var aOffsets: TOffsets);
begin
  SetLength(aOffsets, Length(aOffsets)+1);
  aOffsets[Length(aOffsets)-1] := aOffset;
end;

procedure TFildOffsets.Fild(var aFild: Integer; var aOffsets: TOffsets);
begin
  Add(PByte(@aFild) - PByte(Self), aOffsets);
end;

procedure TFildOffsets.Fild(var aFild: Double; var aOffsets: TOffsets);
begin
  Add(PByte(@aFild) - PByte(Self), aOffsets);
end;

{ TFilds }

class constructor TFilds.Init;
begin
  with TFilds(nil) do begin
    Fild(A, Offsets);
    Fild(D, Offsets);
  end;
end;

Подсластить, добавить версионность и вкушать у камина.
...
Рейтинг: 0 / 0
28.09.2018, 14:26
    #39709862
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
rtticycle
Код: pascal
1.
TFilds = class(TFildOffsets)

Так и я могу. В вопросе речь шла о record. А он классовых конструкторов не умеет
...
Рейтинг: 0 / 0
28.09.2018, 14:37
    #39709871
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_В вопросе речь шла о record. А он классовых конструкторов не умеет
Умеет.
...
Рейтинг: 0 / 0
28.09.2018, 14:39
    #39709872
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
Kazantsev AlexeyУмеет.Прикольно! Не знал. Тогда вопрос снят
...
Рейтинг: 0 / 0
29.09.2018, 13:33
    #39710278
Gator
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смещение поля записи в константы
_Vasilisk_, всё равно это не снимает вопрос соответствия структуры обрабатываемых даннык и класса- обработчика
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Смещение поля записи в константы / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]