Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Вниз

Конструкция record`а.   Найти похожие ветки 

 
Riply ©   (2007-11-03 13:49) [0]

Здравствуйте !
Чем при создании (использовании) отличаются следующие два рекорда:
type
TSysRec = packed record
 NextOffset: ULONG;
 function MyFunct: NTSTATUS;
end;

type
TSysRec = packed record
 NextOffset: ULONG;
end;

?.
Некузяво вышло.
Попробую сформулировать вопрос по-другому:
Допустим есть некий рекорд (TSysRec), с которым
работают(создают, записывают, считывают и т.п.) некие Nt-функции
и менять его размер, "структуру" нельзя ну ни на йоту.
А мне вот приспичило добавить в него свою функцию и все тут :)
Какие изменения в его внутренности внесу и чем это может быть черевато ?


 
palva ©   (2007-11-03 13:55) [1]

А разве record может содержать функцию? Это ведь не struct


 
Riply ©   (2007-11-03 14:01) [2]

> [1] palva ©   (03.11.07 13:55)
> А разве record может содержать функцию? Это ведь не struct

У меня BDS 2006 кушает и, даже, причмокивает :)


 
palva ©   (2007-11-03 14:02) [3]

На пенсию пора...


 
Riply ©   (2007-11-03 14:06) [4]

> [3] palva ©   (03.11.07 14:02)
> На пенсию пора...

Не знание новых "примочек" в последних версиях продукта - отнюдь
не повод для удирания на пенсию. (Без смайлика)
Так что и не мечтай :)


 
Leonid Troyanovsky ©   (2007-11-03 14:07) [5]


> Riply ©   (03.11.07 13:49)  

> и менять его размер, "структуру" нельзя ну ни на йоту.
> А мне вот приспичило добавить в него свою функцию и все

Добавив поле - меняем размер.
Нельзя менять размер - нельзя добавить поле.

"Привязывай" свою функцию другим образом,
например через список: адрес структуры - функция.

--
Regards, LVT.


 
Riply ©   (2007-11-03 14:31) [6]

> [5] Leonid Troyanovsky ©   (03.11.07 14:07)
> Добавив поле - меняем размер.
> Нельзя менять размер - нельзя добавить поле.

А почему не показывает изменение размера:
type
TSysRec = packed record
 NextOffset: ULONG;
end;

TSysRecEx = packed record
 NextOffset: ULONG;
 function SizeOfMe: ULONG;
end;

function TSysRecEx.SizeOfMe:ULONG;
begin
Result := SizeOf(TSysRecEx);
end;

ShowMessage(IntToStr(SizeOf(TSysRec)) + sLineBreak + IntToStr(SizeOf(TSysRecEx))) ?

В обоих случаях - четыре байта.


 
Джо ©   (2007-11-03 15:15) [7]

Ну, в экз. класса тоже адреса его методов не хранятся, они хранятся в классе. Гм, загнул :)


 
Leonid Troyanovsky ©   (2007-11-03 15:23) [8]


> Riply ©   (03.11.07 14:31) [6]

> А почему не показывает изменение размера:

Сдаюсь, не знаю :)

--
Regards, LVT.


 
guav ©   (2007-11-03 15:27) [9]

Методам незачем добавлять что-либо к структуре, пока среди них нет виртуальных методов.
В Майкрософтовских библитотеках для С++ есть наследники винапишных структур которые не содержат собственных полей и виртуальных методов, поэтому бинарно совместимы с соответсвующими базовыми структурами.


 
Riply ©   (2007-11-03 15:30) [10]

> [7] Джо ©   (03.11.07 15:15)
> Ну, в экз. класса тоже адреса его методов не хранятся, они хранятся в классе. Гм, загнул :)

Эта... А можно еще раз и по-медленнее ? :)

> [8] Leonid Troyanovsky ©   (03.11.07 15:23)

Но ведь должно же где-то хранится... Что-то, где-то меняется...
Именно поэтому у меня и появился вопрос о
добавлении ф-ии в "неприкасаемую структуру" :)


 
Riply ©   (2007-11-03 15:33) [11]

> [9] guav ©   (03.11.07 15:27)
> В Майкрософтовских библитотеках для С++ есть наследники винапишных структур
> которые не содержат собственных полей и виртуальных методов,
> поэтому бинарно совместимы с соответсвующими базовыми структурами.

А где-бы посмотреть примеры реализации этого
(наследники винапишных структур...поэтому бинарно совместимы) ?


 
guav ©   (2007-11-03 15:35) [12]

Подозреваю что в Delphi вообще не добавили и не добавят наследование recordов, поэтому виртуальные методы там тоже не должны поддерживатся, и структуры при добавлении методов всегда будут бинарно такими же.
Всё же я бы не смешивал структуру и методы. Если тебе нужно конкретное расположение полей структуры, значит структура не твоя, и не стоит чужую структуру смешивать со своими методами.

> Но ведь должно же где-то хранится...

Что именно должно хранится в _экземпляре_ структуры, специфичное для конкретного экзепляра, если методы статические, и потому должны реализованы одинаково для всех структур данного типа ?


 
Riply ©   (2007-11-03 15:40) [13]

> [12] guav ©   (03.11.07 15:35)
> Что именно должно хранится в _экземпляре_ структуры, специфичное для конкретного экзепляра,
> если методы статические, и потому должны реализованы одинаково для всех структур данного типа ?

Второе


 
Джо ©   (2007-11-03 15:40) [14]

> [10] Riply ©   (03.11.07 15:30)
> > [7] Джо ©   (03.11.07 15:15)
> > Ну, в экз. класса тоже адреса его методов не хранятся,
> они хранятся в классе. Гм, загнул :)
>
> Эта... А можно еще раз и по-медленнее ? :)

Это самое...

 TClass1 = class
 procedure A;
 end;

 TClass2 = class
 procedure A;
 procedure B;
 end;

var
 C1: TClass1;
 C2: TClass2;
begin
 C1 := TClass1.Create;
 C2 := TClass2.Create;
 ShowMessage(IntToStr(C1.InstanceSize));
 ShowMessage(IntToStr(C2.InstanceSize));
end;


 
guav ©   (2007-11-03 15:42) [15]

> (наследники винапишных структур...поэтому бинарно совместимы)
> ?

Если на С++ устроит, то atltypes.h . Могу написать пример на Delphi, но он скорее всего не скомпилится :)


 
guav ©   (2007-11-03 15:43) [16]

> > [12] guav ©   (03.11.07 15:35)
> > Что именно должно хранится в _экземпляре_ структуры, специфичное
> для конкретного экзепляра,
> > если методы статические, и потому должны реализованы одинаково
> для всех структур данного типа ?
>
> Второе

Ээ не понял что второе ?


 
Riply ©   (2007-11-03 15:52) [17]

> [14] Джо ©   (03.11.07 15:40)
> Это самое...

Ну, это совсем другое дело ! :)

> [15] guav ©   (03.11.07 15:42)
> Если на С++ устроит, то atltypes.h .
У меня нет такого файла.

> Могу написать пример на Delphi, но он скорее всего не скомпилится :)
Спасибо не стоит. Лучше тратить время на компилируемые примеры :)


 
Riply ©   (2007-11-03 16:06) [18]

Т.е. резюме такое:
В "неприкасаемую" структуру можно добавить свои ф-ии,
но не стоит, ибо это "порочная практика". ?


 
guav ©   (2007-11-03 16:28) [19]

> > Если на С++ устроит, то atltypes.h .
> У меня нет такого файла.

Ну по мсдн можно глянуть что это
http://msdn2.microsoft.com/en-us/library/t792xy69(VS.80).aspx
Смысл в том что наследник tagPOINT полностью совместим с tagPOINT из Windows.pas, но имеет методы.


> но не стоит, ибо это "порочная практика". ?

Ну это только моё имхо :)
Я бы не стал так делать т.к. имхо расклад полей твоей структуры относится к интерфейсу (тебе нужен конкреный расклад для чтения структуры откуда-либо и/или передачи куда либо, не так ли ?), а методы - к реализации. Полезно разделять интерфейс и реализацию.


 
guav ©   (2007-11-03 16:44) [20]

PS: Я вообще не вижу существенных преимуществ методов рекордов перед свободными функциями принимающими те же рекорды, а вот недостатки вижу.


 
Riply ©   (2007-11-03 17:00) [21]

> [19] guav ©   (03.11.07 16:28)
> Ну по мсдн можно глянуть что это
> http://msdn2.microsoft.com/en-us/library/t792xy69(VS.80).aspx
Спасибо.

> тебе нужен конкреный расклад для чтения структуры откуда-либо
> и/или передачи куда либо, не так ли ?), а методы - к реализации.

Дело вот в чем:
Есть несколько похожих структур.
Они (или их последовательность) возвращаются некими ф-ми.
Иногда мне надо их заполнить вручную в точном соответствии с
правилами заполнения, используемыми в этих ф-иях.
(Корректно заполнить поля смещений, размеров, учитывая выравневание, и т.п.).
Было бы очень удобно определить в них некую ф-ию, которая занималась бы подсчетом
всего этого безобразия и заодно проверяла бы валидность стр-ры.

Надеюсь не очень сумбурно ?


 
guav ©   (2007-11-03 18:30) [22]

> Было бы очень удобно определить в них некую ф-ию, которая
> занималась бы подсчетом
> всего этого безобразия и заодно проверяла бы валидность
> стр-ры.

Ты хочешь полиморфизм средствами языка тут ?
Или ты явно указывешь тип структуры - или у тебя будет одна реализация на все структуры.

Единую реализацию на все структуры лучше оформить так:
function SizeOfMe(var R);
и разумеется там так просто SizeOf(R) не получится.


 
guav ©   (2007-11-03 18:34) [23]

Полиморфизм, который ты возможно хочешь тут, реализуется через информацию о типе, которая бы таки заняла место в рекорде, нарушив бы "неприкасаемость".


 
Riply ©   (2007-11-03 18:57) [24]

> [23] guav ©   (03.11.07 18:34)
> Полиморфизм, который ты возможно хочешь тут, реализуется через информацию о типе,
> которая бы таки заняла место в рекорде, нарушив бы "неприкасаемость".

Нарушать нельзя.
Может тогда что-то такого типа (это можно перевести на Delpi ?):
00203 /*
00204  * PURPOSE: Returns the byte offset of a field within a structure
00205  */
00206 #define FIELD_OFFSET(Type,Field) (LONG)(&(((Type *)(0))->Field))
00207
00208 /*
00209  * PURPOSE: Returns the base address structure if the caller knows the
00210  * address of a field within the structure
00211  * ARGUMENTS:
00212  *          Address = address of the field
00213  *          Type = Type of the whole structure
00214  *          Field = Name of the field whose address is none
00215  */
00216 #define CONTAINING_RECORD(address, type, field) \
00217     ((type *)(((ULONG_PTR)address) - (ULONG_PTR)(&(((type *)0)->field))))


 
guav ©   (2007-11-03 19:12) [25]

> (это можно перевести на Delpi ?):

Это не функции. И даже не шаблоны. Это сишные макросы. Это не прерводится на человеческий язык.
Только вставлять по месту. Или прикручивать препроцессор, на правах седла для коровы.

Уточни свою задачу, или хотя бы приведи пример с более чем одной структурой.

PS: Ставлю Turbo Delphi 2006 чтобы глянуть эти новые особенности синаксиса.


 
Leonid Troyanovsky ©   (2007-11-03 19:25) [26]


> Riply ©   (03.11.07 15:30) [10]

> Но ведь должно же где-то хранится... Что-то, где-то меняется.

В самой записи, как мы убедились, ничего не хранится.
Если взять массив таких записей, можно убедиться,
что он также имеет ожидаемый размер.

Т.к., методы статические, то компилятор имеет возможность
генерировать весь необходимый код в нужных местах,
где вызываются эти методы.
Т.е., получается, что методы имеют видимость
ограниченную однотипными рекордами.

Возможно, что это именно то, что тебе хотелось,
и не думаю, что при описанных действиях
проявятся какие-либо побочные эффекты.

--
Regards, LVT.


 
Riply ©   (2007-11-03 19:44) [27]

> [25] guav ©   (03.11.07 19:12)
> Это не функции. И даже не шаблоны. Это сишные макросы.
> Это не прерводится на человеческий язык.

Вот это ты обрадовал :)

> Уточни свою задачу, или хотя бы приведи пример с более чем одной структурой.
Конкретный пример из проекта не привести.
Слишком много вложенностей и внутренних ссылок :(
Попробую "на пальцах".
Структуры имеют примерно такой вид:
_TEMPLATE_REC = packed record
  ...
  ...
//   NextEntryOffest : ULONG; Пока отбросим это поле.
  DataOffset      : ULONG;
  DataLength      : ULONG;
  NameLength      : ULONG;
  Name            : array[0..0] of WCHAR;
 end;

Где:
... - разные поля в разных рекордах
DataOffset - оффсет до Data (не участвует в рекорде)
Data - следует сразу после Name плюс NameLength, выровненного до DWord.

Кроме всего прочего, надо вычислять(контролировать) DataOffset,
выравнивать полученное и получать размер структуры.
Ф-ии типа, "не прерводится на человеческий язык" сумели бы помочь :)

> PS: Ставлю Turbo Delphi 2006 чтобы глянуть эти новые особенности синаксиса.
В ход пошла тяжелая артилерия ?
А не из пушки это будет по воробъям ?
Может плюнуть и расписывать все это хозяйство персонально для каждой структуры ?


 
Riply ©   (2007-11-03 19:51) [28]

> [26] Leonid Troyanovsky ©   (03.11.07 19:25)
> и не думаю, что при описанных действиях
> проявятся какие-либо побочные эффекты.

Спасибо. Именно это меня и беспокоило.
Осталось урегулировать вопрос с "является ли порочной"
практика внесения своих методов в чужие (тем более Microsoft`кие) структуры ?


 
Leonid Troyanovsky ©   (2007-11-03 19:52) [29]


> Riply ©   (03.11.07 19:44) [27]

> Может плюнуть и расписывать все это хозяйство персонально
> для каждой структуры ?

А их в любом случае надо расписывать персонально.
Структуры не наследуются, разные - несовместимы по присваиванию.

--
Regards, LVT.


 
Riply ©   (2007-11-03 19:59) [30]

> [29] Leonid Troyanovsky ©   (03.11.07 19:52)
> А их в любом случае надо расписывать персонально.
>Структуры не наследуются, разные - несовместимы по присваиванию.

Мне кажется, что можно выкрутиться, создав Temlate структуру,
в которой определить нужные ф-ии (с учетом Sender`а),
и в нужном месте использовать приведение рабочих ст-р к Temlate`у.

P.S.
Это только в проекте, еще не реализовано.


 
Leonid Troyanovsky ©   (2007-11-03 20:01) [31]


> Riply ©   (03.11.07 19:51) [28]

> Осталось урегулировать вопрос с "является ли порочной"
> практика внесения своих методов в чужие (тем более Microsoft`кие)
> структуры ?

Если не планируется портировать на те языки, в которых
подобных средств нет, то почему бы и нет.
Ясно, что это проще, т.е. позволяет избежать многих ошибок.

Ну, а MS это, видимо, по барабану, т.к. сами структуры
не затрагиваются.

Только, мне кажется, что надо избегать методов-функций,
возвращающих указатель на саму структуру, чтоб
не соблазняться использованием вместо структуры.
Если все методы будут процедурами будет спокойней, IMHO.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2007-11-03 20:13) [32]


> Riply ©   (03.11.07 19:59) [30]

> Мне кажется, что можно выкрутиться, создав Temlate структуру,

Скорее всего методы структур устроены подобно методам классов,
и принимают неявный параметр с указателем на рекорд.
Может быть и существует способ использования регулярных процедур
в качестве основы для базовых методов.

--
Regards, LVT.


 
Riply ©   (2007-11-03 20:15) [33]

> [31] Leonid Troyanovsky ©   (03.11.07 20:01)
> Если не планируется портировать на те языки, в которых
> подобных средств нет, то почему бы и нет.
> Ясно, что это проще, т.е. позволяет избежать многих ошибок.

> Ну, а MS это, видимо, по барабану, т.к. сами структуры
> не затрагиваются.

Ну раз еще и вопрос с "нравственностью" улажен
(один голос(guav) против, два(Leonid Troyanovsky, Riply) - за),
то можно попробовать приступить к реализации. :)


 
Riply ©   (2007-11-03 20:18) [34]

> [33] Riply ©   (03.11.07 20:15)
> то можно попробовать приступить к реализации.

P.S.
А все таки жаль, что нет "это не прерводится на человеческий язык" ф-ий :)


 
guav ©   (2007-11-03 20:21) [35]

> _TEMPLATE_REC = packed record
>  ...
>  ...
> //   NextEntryOffest : ULONG; Пока отбросим это поле.
>  DataOffset      : ULONG;
>  DataLength      : ULONG;
>  NameLength      : ULONG;
>  Name            : array[0..0] of WCHAR;
> end;


Можно выдумать что-то вроде
type TCommonPart = packed record
 DataOffset      : ULONG;
 DataLength      : ULONG;
 NameLength      : ULONG;
 Name            : array[0..0] of WCHAR;
end;

type TSomeRec1 = packed record
...
commonPart: TCommonPart;
end;

type TSomeRec2 = packed record
...
commonPart: TCommonPart;
end;

function  InitRec(var R; // сам record
                 sizeOfR: ULONG; // размер record
                 var commonPart: TCommonPart; // общая часть, д.б. внутри R и это легко сделать проверяемым.
                 ... // можно передавать Name и Data сюда же

TCommonPart можно поместить в начало рекордов, тогда на один параметр InitRec меньше и все действия станут понятнее.

Вообще ты наверное не на том языке пишешь :) если хочешь что-то вроде [24]. Попробуй С.


> > PS: Ставлю Turbo Delphi 2006 чтобы глянуть эти новые особенности  синаксиса.
> В ход пошла тяжелая артилерия ?

Я просто захотел глянуть что это за новинка - методы в рекордах.
Дело в том что если бы кроме этой фичи ничего бы не добавилось в рекорды, то сама по себе фича была бы почти бесполезна. Теперь выяснил, что там ещё добавились области видимости и свойства в рекорды, при совместном использовании всего этого можно извлечь пользу.


 
Leonid Troyanovsky ©   (2007-11-03 20:34) [36]


> Leonid Troyanovsky ©   (03.11.07 20:13) [32]

> Может быть и существует способ использования регулярных
> процедур
> в качестве основы для базовых методов.

Ну, я и намудрил :)
Регулярные процедуры просто вызываются с параметром-рекордом.
Т.е., общие действия совершаются глобальными процедурами,
а специфические - методами рекордов.

--
Regards, LVT.


 
Riply ©   (2007-11-03 21:12) [37]

> [35] guav ©   (03.11.07 20:21)
> Можно выдумать что-то вроде
......
Примерно так я и планировала, с маленькой попроавкой:
У всех структур есть простенькие ф-ии GetInfo и SetParams.
Temlate вызывает GetInfo, считает(контролирует) и преобразует все что надо,
и вызывает SetParams. Тогда можно считать, что параметры почти не нужны :)

> Вообще ты наверное не на том языке пишешь :)
> если хочешь что-то вроде [24]. Попробуй С.

Ой и не говори... Но "лошадей на переправе не меняют" ?

P.S.
Медленно, от силы по часику в день,
пытаюсь выделить на С, но это "мертвому припарки" :(
Единственное, чему научилась - не падать в обморок при виде С-шного кода :)


 
Riply ©   (2007-11-03 21:13) [38]

> [36] Leonid Troyanovsky ©   (03.11.07 20:34)
> Ну, я и намудрил :)

Ничего, я правильно поняла :)


 
vpbar ©   (2007-11-04 18:13) [39]

Чем при создании (использовании) отличаются следующие два рекорда:
type
TSysRec = packed record
NextOffset: ULONG;
function MyFunct: NTSTATUS;
end;

type
TSysRec = packed record
NextOffset: ULONG;
end;
При создании ни чем. Т.е. в памяти они имеют (насколько я понимаю) одинаковую структуру. При использовании во втором случае можно сделать  
так  

SR:TSysRec;
SR.MyFunct;

а в первом нельзя. Но можно так
function MyFunct(const value:TSysRec):NTSTATUS;
 MyFunct(SR);

что по сути одно и тоже, и SR.MyFunct - просто синтаксический сахар.

Какие изменения в его внутренности внесу и чем это может быть черевато ?
Насколько я знаю, если просто добавить функцию в record то никаких изменений в его структуру это не внесет (по крайней мере в BDS2006 обратного мне не встречалось). Ибо не нужны никакие изменения.

Мне кажется, что можно выкрутиться, создав Temlate структуру,
в которой определить нужные ф-ии (с учетом Sender`а),
и в нужном месте использовать приведение рабочих ст-р к Temlate`у.

В смысле _TEMPLATE_REC(WORK_REC) ?? Нууу. А может  тогда использовать packed class?

TSysRecС = packed class
NextOffset      : ULONG;
DataOffset      : ULONG;
DataLength      : ULONG;
NameLength      : ULONG;
Name            : array[0..0] of WCHAR;
function MyFunct: Boolean;
end;

Для удобства. А во внешние функции возвращать указатель (PSysRec(Integer(TSysRecС)+4)  или временную переменную нужного типа.


 
vpbar ©   (2007-11-04 18:14) [40]

>>При использовании во втором случае можно сделать
Гы. Наоборот



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.58 MB
Время: 0.043 c
2-1194021209
Riply
2007-11-02 19:33
2007.11.25
Не юникодные платформы.


15-1192964581
DVM
2007-10-21 15:03
2007.11.25
Опять анкета не найдена


1-1188751429
ins
2007-09-02 20:43
2007.11.25
Видео в TWebBrowser


15-1192696621
Начальник ИТ
2007-10-18 12:37
2007.11.25
Организация передачи данных по диал-ап соединению


6-1174306146
Vostrik
2007-03-19 15:09
2007.11.25
IdSMNP





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский