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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.005 c
15-1447832032
Dimka Maslov
2015-11-18 10:33
2016.07.24
Вот интересно


15-1444253403
Юрий
2015-10-08 00:30
2016.07.24
С днем рождения ! 8 октября 2015 четверг


15-1443426766
Empleado
2015-09-28 10:52
2016.07.24
RAD Studio Upgrade + free tools


4-1278077072
Festil
2010-07-02 17:24
2016.07.24
Инициализация драйвера камеры.


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





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский