Сейчас на форуме: tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› Найти список полей класса
Посл.ответ Сообщение

Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 24 февраля 2008 20:46
· Личное сообщение · #1

Всем привет. Вопрос к программистам. Сам прогаю на Delphi, но если на Delphi мою задачу не решить или вы знаете как это сделать другими средствами то подойдут и они. Вобщем дело было так.
Мне нужно на этапе выполнения, зная лишь адресу переменной, узнать ее структуру: тип и размер. С размером все понятно. Есть SizeOf. А вот с типом сложнее. Мне не обязательно знать тип как таковой. Достаточно будет знать что это либо определенная структура, либо ссылка структуру.
Например, если это переменная типа Integer, то мне нужно знать что, это структура из одного элемента занимающая 4 байта. Если это массив [0..10] of Byte, то это структура из десяти структур, размер каждой из которых 1 байт (хотя конечно общий объем занимаемой памяти будет скорее всего 16 байт, но с размером, как я уже говорил, вроде разобратся можно). Если переменная - это динамический массив классов, то это уже ссылка на структуру из N-ого кол-ва элементов, каждый из которых является ссылкой на структуру. Если переменная - это класс или запись, то мне нужно знать колличество полей, и размер каждого. Зная это, я найду адрес каждого поля, а значит и информацию по каждому из них отдельно.
Скажите, возможно ли это впринципе. Если да то, какими средствами, в каком направлении капать?



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 24 февраля 2008 21:05 · Поправил: HiEndsoft
· Личное сообщение · #2

sibedir пишет:определенная структура, либо ссылка структуру
Если 4 байта представляют из себя DWORD-адрес, который лежит в диапазоне адресов сегм. данных твоего приложения => значит, очевидно, это указатель. копай VirtualQuery и т.п.
sibedir пишет:С размером все понятно. Есть SizeOf. А вот с типом сложнее
а что в делфях не как у всех и, например 4 байта это м/б не ULONG, 1 байт м/б не char?

-----
продавец резиновых утёнков




Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 24 февраля 2008 21:15
· Личное сообщение · #3

Если 4 байта представляют из себя DWORD-адрес, который лежит в диапазоне адресов сегм. данных твоего приложения => значит, очевидно, это указатель
Не факт, велика вероятность ошибки. Эти 4 байта могут быть и простым числов Integer. Где-то есть информация о переменной. Она хранится в памяти около адреса переменной. Например, размер переменной хранится, помоему, а 4-х байтах от адреса переменной назад. Тоесть отнимите от адреса переменной 4 и получите адрес, где хранится размер. Для остальной информации есть что-то подобное, но вот подробнее я уже не нашел.



Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 24 февраля 2008 21:17
· Личное сообщение · #4

а что в делфях не как у всех и, например 4 байта это м/б не ULONG, 1 байт м/б не char?
4 байта может быть и Integer и Pointer, а это разные вещи.



Ранг: 48.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 25 февраля 2008 00:14
· Личное сообщение · #5

sibedir
Мне нужно на этапе выполнения, зная лишь адресу переменной, узнать ее структуру: тип и размер. С размером все понятно. Есть SizeOf.

С каких пор sizeof стала работать на этапе выполнения?

Скажите, возможно ли это впринципе. Если да то, какими средствами, в каком направлении капать?

Только если эта информация хранится где-то в исполняемом файле в явном виде(как например в байткоде Явы). С обычным машинным кодом это невозможно. Можно только попытаться придумать какие-то эвристики.



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 25 февраля 2008 08:52
· Личное сообщение · #6

sibedir пишет:
Скажите, возможно ли это впринципе. Если да то, какими средствами, в каком направлении капать?

Для чистого кода лучше ИДы задолбаешься придумывать (туда и копай =)).

-----
Всем привет, я вернулся




Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 25 февраля 2008 09:14
· Личное сообщение · #7

HiEndsoft пишет:
копай VirtualQuery и т.п

Наврятли, HiEndsoft. В информации о виртуальном адресном пространстве не содержится данных о конкретных блоках и их назначении.

Stiver пишет:
С каких пор sizeof стала работать на этапе выполнения?

На этапе выполнения, значит в процессе выполнения откомпелированной программы. Именно на этом этапе и работают все процедуры и функции. Акцентируя внимание на этап, я имел в веду, что на этапе программирования, написания кода, я собственными глазами могу посмотреть структуру любого типа, а значит, могу делать с этим адресным пространством все что захочу, не опасаясь негативно повлиять на работоспособность приложения. Но мне не всегда заранее известна структура типа. Если например моя функция реализована в библиотеке, которую я единажды создал, и далее использую в других приложениях, не изменяя саму библу, то мне придется программно выдерать инфу о типе данных, хранимых под определенным адресом. Я хотел написать универсальную функцию, которая по адресу сама определяла, что за данные. Пока я могу лишь определить адреса и размеры данных. Этого мне может и хватило бы, но мне мешает тот факт, что сами данные могут не хранится именно в этом адресном пространстве, а это может быть всего лишь ссылка. Так вот я и хотел найти способ, как отделить ссылки (Pointer) от непосредственно данных.
Stiver пишет:
Только если эта информация хранится где-то в исполняемом файле в явном виде(как например в байткоде Явы). С обычным машинным кодом это невозможно

Видимо вы правы. Но всеравно, спасибо всем за уделенное время.
Будут идеи пишите в эту тему, буду очень признателен.



Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 25 февраля 2008 09:15
· Личное сообщение · #8

Bitfry пишет:
Для чистого кода лучше ИДы задолбаешься придумывать (туда и копай =)).

А что такое "ИДы".




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 25 февраля 2008 09:34
· Личное сообщение · #9

sibedir пишет:
что такое "ИДы"

Дизассемблер IDA. В любом случае это сопряжено с гемором будет.



Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 25 февраля 2008 10:16
· Личное сообщение · #10

А что мне в данном случае даст дизассемблер?



Ранг: 48.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 25 февраля 2008 11:12
· Личное сообщение · #11

sibedir
На этапе выполнения, значит в процессе выполнения откомпелированной программы. Именно на этом этапе и работают все процедуры и функции.

К сожалению это неверно. Советую на досуге почитать документацию.

sizeof is a compile-time operator that returns the size, in bytes, of the variable or parenthesized type-specifier that it precedes

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



Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 25 февраля 2008 13:15
· Личное сообщение · #12

Спасибо за пояснение, Stiver. Получается, что функция SizeOf не компелируется как функция таковая, а просто компилятор подставляет в код конкретное число. Это приоткрыло мне глаза на некоторые механизмы.



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 25 февраля 2008 13:53
· Личное сообщение · #13

SizeOf придумана для гибкости программирования-это RT-константа. Твою задачу можно решить только написанием дизассемблера-отладчика. Константы можно попробовать выдрать ч/з PE. Зачем тебе это?
При работе с API или уже с известными при дизассемблировании ф-циями можно видеть значения структур и переменных при сплайсинге и подмене адреса возврата.
Кстати, например в новых msvcrt7-8, .NET и т.п. много экспортируемых структур, так что можно все о них узнать.

-----
продавец резиновых утёнков




Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 25 февраля 2008 14:23
· Личное сообщение · #14

HiEndsoft пишет:
Зачем тебе это?

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



Ранг: 122.2 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 25 февраля 2008 16:29
· Личное сообщение · #15

Единственная возможно получать инфу о типе данных в рантайме в Delphi (native а не .Net) - это использовать классы с включенной RTTI. И то инфа будет ограниченная по сравнению с .Net или Java.



Ранг: 284.8 (наставник), 6thx
Активность: 0.150
Статус: Участник

Создано: 25 февраля 2008 17:14
· Личное сообщение · #16

Ну так если размер у проги не большой, то залей куда-нить, авось время у кого-нить будет - помогут, а так гадать бесполездно, тем более без дизасма или рантайма!!!



Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 26 февраля 2008 06:33 · Поправил: sibedir
· Личное сообщение · #17

Кажется нашел. Это действительно RTTI. Я поначалу тут и копал, но меня сбило то, что во всех источниках, которые я смотрел, говорилось лишь об информации класса из раздела published. Но как оказалось RTTI - намного белее продвинутая, хотя и недокументируемая, технология.

Как закончу изучать, сразу сюда отпишусь.



Ранг: 14.5 (новичок)
Активность: 00.01
Статус: Участник

Создано: 27 февраля 2008 19:34
· Личное сообщение · #18

sibedir пишет:
Хотел написать единую процедуру для сохранения объектов в файл и загрузки из файла.

а смотрел ченить типа TWriter.WriteComponent
делфи же сохраняет формы в ресурсы при компиляции и загружает объекты из ресурсов когда форму создает в рантайме
вроде там уже есть все готовое



Ранг: 5.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 29 февраля 2008 06:04
· Личное сообщение · #19

Короче труба. RTTI - вешь конечно хорошая. Но проблема в том, что к таким типам как Pointer или TClass методы этой технологии не подходят. А мне они ой как нужны. Выход один - нужно самому в каждом классе регистрировать каждое поле, в общем реализовать что-то типа своего RTTI. Но это уже не имеет смысла. Я с таким же успехом для каждого класса напишу процедуру сохранения, как это всегда и делается. Ну да бог с ним. Как говорится - попытка не пытка. А то, что я хотел узнать, я узнал.
Всем без исключения спасибо, что пытались помочь и помогли.





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 29 февраля 2008 21:14
· Личное сообщение · #20

sibedir, короче reflection в С++ нормально не сделать, т.к. информации о типах в откомпиленом коде почти нету. Но, есть куча более-менее приличных решений для serialization. Например: www.boost.org/libs/serialization/doc/index.html


 eXeL@B —› Программирование —› Найти список полей класса
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати