Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.07.24;
Скачать: CL | DM;

Вниз

Record -> String   Найти похожие ветки 

 
K-1000 ©   (2015-10-20 10:48) [0]

Всем привет.
Можно ли с помощью RTTI (D7) любую структуру перевести в строку?


var
 PenData: TPenData;
begin
 Label1.Caption:= RecordToString(PenData);
end;


 
Sha ©   (2015-10-20 10:56) [1]

нельзя


 
virex(home) ©   (2015-10-20 11:30) [2]

в delphi7 структура не является классом, в отличие от c# и java где все (?) примитивы имеют обертки-классы, позволяющие сделать что-то типа PenData.ToString()
з.ы. мысли вслух


 
Юрий Зотов ©   (2015-10-20 13:29) [3]

Насколько помню, в D7 RTTI для record"ов не генерируется. Значит - нельзя.


 
DVM ©   (2015-10-20 13:38) [4]


> K-1000 ©   (20.10.15 10:48) 


> Можно ли с помощью RTTI (D7) любую структуру перевести в
> строку?

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


 
Юрий Зотов ©   (2015-10-20 13:40) [5]

Но можно представить в виде HEX-строки память, которую занимает запись. Если, конечно, в ней нет ссылочных полей.


 
K-1000 ©   (2015-10-20 14:26) [6]


> Sha ©   (20.10.15 10:56) [1]
>
> нельзя


А в новых Дельфи?

>virex(home) ©   (20.10.15 11:30) [2]
>в delphi7 структура не является классом, в отличие от c# и java где все (?) >примитивы имеют обертки-классы, позволяющие сделать что-то типа >PenData.ToString()
>з.ы. мысли вслух

RTTI может энум TBrushStyle перевести в строку.
Который не является TObject"ом.

> DVM ©   (20.10.15 13:38) [4]
> Ты же как правило с определенными структурами работаешь. И их скорее
> всего небольшое количество. Что мешает написать для них функции?

Так и делаю пока. Но у многих API есть длиннющие и загадочные структуры как TDeviceMode или Директовские структуры, в которых нужно посмотреть нужные поля, а желательно все.


> Юрий Зотов ©   (20.10.15 13:40) [5]
>
> Но можно представить в виде HEX-строки память, которую занимает
> запись. Если, конечно, в ней нет ссылочных полей.


Можно поподробнее?


 
Sha ©   (2015-10-20 14:57) [7]

BinToHex, HexToBin


 
Kerk ©   (2015-10-20 15:13) [8]


> K-1000 ©   (20.10.15 14:26) [6]
>  
> > Sha ©   (20.10.15 10:56) [1]
> >
> > нельзя
>
> А в новых Дельфи?

В новых можно
http://stackoverflow.com/a/23824290


 
Юрий Зотов ©   (2015-10-20 16:36) [9]

Ниже - еще один велосипед (чтобы совсем уж не забыть Delphi).
Писал навскидку, возможны ошибки.


const
 HexDigits: array[0..$F] of char =
   ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");

function MemoryAsHexString(p: PByte, size: integer): AnsiString;
var
 i: integer;
 t: byte;
begin
 SetLength(Result, size * 2);
 for i := 0 to (size - 1) do
 begin
    t := p^ shr 4;
    Result[2 * i + 1] = HexDigits[t];
    t := p^ and $F;
    Result[2 * i + 2] = HexDigits[t];
    inc(p);
  end
end;

// Пример вызова:

var
  AnyRecord = record // здесь лучше, но не обязательно: packed record
 ... // здесь не должно быть ссылочных полей
 end;

MemoryAsHexString(PByte(@MyRecord), SizeOf(MyRecord));


 
K-1000 ©   (2015-10-20 19:42) [10]


> Kerk ©   (20.10.15 15:13) [8]
>
>
> > K-1000 ©   (20.10.15 14:26) [6]
> >  
> > > Sha ©   (20.10.15 10:56) [1]
> > >
> > > нельзя
> >
> > А в новых Дельфи?
>
> В новых можно
> http://stackoverflow.com/a/23824290


С Delphi XE 2?


 
Германн ©   (2015-10-21 01:12) [11]


> Но у многих API есть длиннющие и загадочные структуры

И при чём тут RTTI?


 
K-1000 ©   (2015-10-21 20:04) [12]


> Германн ©   (21.10.15 01:12) [11]
>
>
> > Но у многих API есть длиннющие и загадочные структуры
>
> И при чём тут RTTI?
>


Чтобы RTTI мне помог такие структуры переводить в строку.


 
Kerk ©   (2015-10-21 20:42) [13]


> K-1000 ©   (20.10.15 19:42) [10]
>
> С Delphi XE 2?

С Delphi 2010, если я не ошибаюсь.


 
Германн ©   (2015-10-22 00:31) [14]


> K-1000 ©   (21.10.15 20:04) [12]
>
>
> > Германн ©   (21.10.15 01:12) [11]
> >
> >
> > > Но у многих API есть длиннющие и загадочные структуры
> >
> > И при чём тут RTTI?
> >
>
>
> Чтобы RTTI мне помог такие структуры переводить в строку.
>

RTTI есть только у Дельфийских классов. Ну т.е. то RTTI, которое тебе доступно в Дельфийской программе. Откуда она возьмётся в некоем стороннем API?


 
Кто б сомневался ©   (2015-10-22 03:21) [15]


> Чтобы RTTI мне помог такие структуры переводить в строку.


Строка это тоже структура, но одного вида, а твоя структура другого вида. Чтобы все работало, нужно описать что, как и куда превращать.

Короче это можно сделать через перегруженные операторы - operator overloading (не помню когда они появились, может и в Delphi ЧУ2), после этого можно делать так:

var
 PenData: TPenData;
begin
 Label1.Caption:= PenData;
 //  и наборот
 PenData := Label1.Caption;

end;



TString256 = record  // это любая структура
   fArrayChr : array [0..255] of char;
   class operator Implicit(const aRec: TString256): string; // переводим структуру в строку
   class operator Implicit(const aStr: string): TString256;  // и строку в свою структуру
 end;

class operator TString256.Implicit(const aStr: string): TString256;
begin
 DoImplicit(aStr, @Result.fArrayChr[0], SizeOf(Result.fArrayChr));
end;

class operator TString256.Implicit(const aRec: TString256): string;
begin
 Result := aRec.fArrayChr;
end;

procedure DoImplicit(const aStr: string; aBuf: Pointer; aSize: integer);
const
 FMT_MSG = "Implicit overloading error. Buf size: %d, String Size: %d";
var
 vSize: integer;
begin
 ZeroMemory(ABuf, aSize);  
 if Length(aStr) = 0 then exit;
 vSize := Length(aStr) * SizeOf(Char);
 //Assert(vSize <= aSize, Format(FMT_MSG, [aSize div 2, vSize]));
 if vSize > aSize then
   vSize := aSize;

 Move(aStr[1], ABuf^, vSize);
end;


DoImplicit не нужно делать отдельной процедурой, просто кусок из кода выдрал.


 
K-1000 ©   (2015-10-22 15:36) [16]


> Германн ©   (22.10.15 00:31) [14]
> RTTI есть только у Дельфийских классов. Ну т.е. то RTTI,
>  которое тебе доступно в Дельфийской программе. Откуда она
> возьмётся в некоем стороннем API?


Мне нужно конвертировать длинные структуры какого угодно API, будь это WinAPI, OGGVORBIS или DX.

> Кто б сомневался ©   (22.10.15 03:21) [15]

Мммм... Не понятно это код может перевести допустим структуру
Windows.TDeviceModeA в строку.


 
Игорь Шевченко ©   (2015-10-22 16:20) [17]


> Мне нужно конвертировать длинные структуры какого угодно
> API, будь это WinAPI, OGGVORBIS или DX.


Стесняюсь спросить, с какой целью ?


 
Юрий Зотов ©   (2015-10-22 17:32) [18]

> Игорь Шевченко ©   (22.10.15 16:20) [17]

+1. Похоже на X, Y, Z.


 
Кто б сомневался ©   (2015-10-22 18:07) [19]


> K-1000 ©   (22.10.15 15:36) [16]
>
>
> Мне нужно конвертировать длинные структуры какого угодно
> API, будь это WinAPI, OGGVORBIS или DX.


Ах вон оно чё.

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

И поэтому любой хороший программист будет спрашивать с какой целью вы это собираетесь делать, - так требует правила тайного культа, - что вы на стороне добра и не хакер случайно вдруг.


 
Andy BitOff ©   (2015-10-22 19:22) [20]


> и не хакер случайно вдруг.

Свят, свят, свят. Упаси нас бог.


 
K-1000 ©   (2015-10-22 19:37) [21]


> Игорь Шевченко ©   (22.10.15 16:20) [17]
>
>
> > Мне нужно конвертировать длинные структуры какого угодно
> > API, будь это WinAPI, OGGVORBIS или DX.
>
>
> Стесняюсь спросить, с какой целью ?


С той же, что и вопрос со СтэкОферфлоу:
"access all elements of a record using RTTI".

Бывает так, что некоторые поля структуры не ясно что содержат.
Даже читая MSDN не ясно, что именно будет в поле.
Тот же MSDN допустим утверждает, что поле TDisplayDeviceA.DeviceId -
Not used. А если посмотреть самому, то это поле возвращает нужные данные.
Как бы я это узнал, если бы не сделал полную конвертацию структуры в строку? Никак.

Ещё у многих API есть море длиннющих структур, хочется в поисках доп. информации или ради простого любопытства посмотреть "А что там?".
Тем более некоторые структуры имеют плохую документацию. Или структура является вообще недокументированной. (Привет, мастеру Rouse_)

Писать для каждой структуры свою функцию конвертирования в строку...
Нудно. Можно конечно сделать простой парсер текстового представления структуры... Но как ясно из ветки, с этим может справиться нынешний RTTI.

Да и вопрос скорее ради "А может ли Delphi". Как вижу, может.


 
Кто б сомневался ©   (2015-10-22 20:07) [22]

[21]

> Тот же MSDN допустим утверждает, что поле TDisplayDeviceA.
> DeviceId -
> Not used. А если посмотреть самому, то это поле возвращает
> нужные данные.
> Как бы я это узнал, если бы не сделал полную конвертацию
> структуры в строку? Никак.
>


Zenais, futuebam matrem tuam!
Извините за мой латинский.

Чтобы посмотреть что в структуре, нужно поставить точку остановки (breakpoint) - в том месте где она используется. Потом запустить прогу в отладчике Delphi - и когда остановится на этой точке - навести курсор на эту структуру (переменную) и нажать Ctrl + Shift + Клик левой мышью.
Так можно посмотреть любую переменную.
Появиться окошко ,которое покажет все содержимое структуры, разбитое по названиями - значениям итд.
И можно дальше трассировать и значения будут меняться в этом окошке.


 
Юрий Зотов ©   (2015-10-22 22:06) [23]

> Появиться окошко ,которое покажет все содержимое структуры,
> разбитое по названиями - значениям итд.


Причем эти данные можно будет смотреть уже с учетом порядка хранения байт в памяти. Чего не покажет строка.


 
Юрий Зотов ©   (2015-10-23 05:29) [24]

> K-1000 ©   (20.10.15 10:48)
> Можно ли с помощью RTTI (D7) любую структуру перевести в строку?


Почему бы было не задать изначальный вопрос? Например: "как увидеть содержимое структуры?".

Типичное X, Y, Z: http://www.gunsmoker.ru/2008/10/x-y-z.html


 
K-1000 ©   (2015-10-25 15:54) [25]


> Кто б сомневался ©   (22.10.15 20:07) [22]
>
> [21]


Отладчиком ещё не пользовался. :)


> Юрий Зотов ©   (23.10.15 05:29) [24]
>
> > K-1000 ©   (20.10.15 10:48)
> > Можно ли с помощью RTTI (D7) любую структуру перевести
> в строку?
>
> Почему бы было не задать изначальный вопрос? Например: "как
> увидеть содержимое структуры?".
>
> Типичное X, Y, Z: http://www.gunsmoker.ru/2008/10/x-y-z.
> html


Ну не знал я, что можно увидеть структуру не в виде строки.


 
Юрий Зотов ©   (2015-10-25 20:06) [26]

> K-1000 ©   (25.10.15 15:54) [25]

Это нормально. Каждый из нас чего-нибудь не знает. Даже самые-самые просветленные из просветленных.
:o)

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

Кстати. Пусть поле структуры - это 4-х байтовое беззнаковое целое 875770417. В 16-ричном виде это число равно $34333231, но на платформе Х86/32 в памяти будет записано $31323334 (такова особенность платформы).

В итоге - при просмотре в виде ANSI-строки увидим совсем другое "число": 1234. Для получения "правильного" числа потребуются ручные преобразования (в которых, к тому же, легко ошибиться). А при просмотре отладчиком можно указать нужный режим - и все преобразования будут сделаны автоматически.


 
Кто б сомневался ©   (2015-10-28 15:11) [27]


> Юрий Зотов ©   (25.10.15 20:06) [26]


+1
Еще момент, а то как оказалось некоторые (многие?) этого не знают. Помню когда работал в одной компании, мне сказали не использовать record"ы, а использовать классы вместо них, пришлось объяснять.

Структура (в Delphi - record) - это трафарет для куска памяти. Есть кусок памяти размером в 10 байт.
И на него можно "положить" разные трафареты, которые будут давать разные значения, в зависимости от размеров полей в структуре.
Любую структуру можно скопировать куда угодно c помощью Move - просто копируем один  кусок памяти в другой (например в строку, только при исп. Move нужно заранее выделить память для строки SetLength).


 
Кто б сомневался ©   (2015-10-28 15:22) [28]

Так вот, вся проблема при копировании одного в другое - это интерпретация этих данных - т.е. как их читать потом юзеру.
В строке string они будут выглядеть по другому - т.к. у строки один символ (char) = 1 байт, а с Delphi 2009 один char в string = 2 байта (т.к. юникод) + там ньюансы с Pchar текстом - обычно в структурах дают адрес на кусок текста "где-то там в памяти" - поэтому текст в строку string не попадет, а только его адрес ну и др.  

И кстати переходи с Dephi 7 на более новую. Там реально удобнее. На XE5 например или выше. И программы быстрее работают, т.к. используют сразу юникод версии функций Win API, без предварительной конвертации (в Windows, ANSI функции сначала конвертируются в юникод (самой Виндой, тут Delphi не причем), а потом вызываются).


 
Кто б сомневался ©   (2015-10-28 15:39) [29]


> Есть кусок памяти размером в 10 байт.


Это для примера конечно же, размер структуры (куска памяти с которого читаем) может быть любой


 
Кто б сомневался ©   (2015-10-28 16:01) [30]


> т.к. у строки один символ (char) = 1 байт, а с Delphi 2009
> один char в string = 2 байта (т.к. юникод) +


integer например = 4 байтам. Pointer тоже = 4 (в x64 версии = 8 байтам).
Поэтому при просмотре строки как текста, она будет показана юзеру как набор однобайтных Char ов (если ANSI string). Например если напрямую перекинуть (Move)  какое то число хранящееся в integer (4 байта), то оно будет "разбросано" (интерпретировано как) на 4 символа char (char = 1 байту), будет 4 разных числа.
И это не какая-то особенность Delphi, а техническая особенность, которая есть во всех нативных языках и платформах.
Чтобы узнать размер структуры - SizeOf().


 
K-1000 ©   (2015-10-28 16:30) [31]


> Кто б сомневался ©   (28.10.15 15:22) [28]

> И кстати переходи с Dephi 7 на более новую. Там реально
> удобнее. На XE5 например или выше. И программы быстрее работают,
>  т.к. используют сразу юникод версии функций Win API, без
> предварительной конвертации (в Windows, ANSI функции сначала
> конвертируются в юникод (самой Виндой, тут Delphi не причем),
>  а потом вызываются).
>


Да вот устанавливаю "Delphi 10 Seattle Lite".
Думаю меня ждёт "лёгкий шок" после "Delphi 7" 2002-го выпуска. :)


 
Юрий Зотов ©   (2015-10-28 19:57) [32]

> Структура (в Delphi - record) - это трафарет для куска памяти.
>
> разные трафареты ... будут давать разные значения
>
> вся проблема ... интерпретация этих данных


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



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

Текущий архив: 2016.07.24;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.018 c
2-1413879971
Alex_C
2014-10-21 12:26
2016.07.24
Своя отрисовка TMemo


15-1446240602
Юрий
2015-10-31 00:30
2016.07.24
С днем рождения ! 31 октября 2015 суббота


15-1442179801
Юрий
2015-09-14 00:30
2016.07.24
С днем рождения ! 14 сентября 2015 понедельник


2-1412944569
Mass
2014-10-10 16:36
2016.07.24
прилипание


15-1443562204
Юрий
2015-09-30 00:30
2016.07.24
С днем рождения ! 30 сентября 2015 среда