Сейчас на форуме: tyns777, zombi-vadim (+3 невидимых) |
![]() |
eXeL@B —› Программирование —› Найти список полей класса |
Посл.ответ | Сообщение |
|
Создано: 24 февраля 2008 20:46 · Личное сообщение · #1 Всем привет. Вопрос к программистам. Сам прогаю на Delphi, но если на Delphi мою задачу не решить или вы знаете как это сделать другими средствами то подойдут и они. Вобщем дело было так. Мне нужно на этапе выполнения, зная лишь адресу переменной, узнать ее структуру: тип и размер. С размером все понятно. Есть SizeOf. А вот с типом сложнее. Мне не обязательно знать тип как таковой. Достаточно будет знать что это либо определенная структура, либо ссылка структуру. Например, если это переменная типа Integer, то мне нужно знать что, это структура из одного элемента занимающая 4 байта. Если это массив [0..10] of Byte, то это структура из десяти структур, размер каждой из которых 1 байт (хотя конечно общий объем занимаемой памяти будет скорее всего 16 байт, но с размером, как я уже говорил, вроде разобратся можно). Если переменная - это динамический массив классов, то это уже ссылка на структуру из N-ого кол-ва элементов, каждый из которых является ссылкой на структуру. Если переменная - это класс или запись, то мне нужно знать колличество полей, и размер каждого. Зная это, я найду адрес каждого поля, а значит и информацию по каждому из них отдельно. Скажите, возможно ли это впринципе. Если да то, какими средствами, в каком направлении капать? ![]() |
|
Создано: 24 февраля 2008 21:05 · Поправил: HiEndsoft · Личное сообщение · #2 sibedir пишет:определенная структура, либо ссылка структуру Если 4 байта представляют из себя DWORD-адрес, который лежит в диапазоне адресов сегм. данных твоего приложения => значит, очевидно, это указатель. копай VirtualQuery и т.п. sibedir пишет:С размером все понятно. Есть SizeOf. А вот с типом сложнее а что в делфях не как у всех и, например 4 байта это м/б не ULONG, 1 байт м/б не char? ----- продавец резиновых утёнков ![]() |
|
Создано: 24 февраля 2008 21:15 · Личное сообщение · #3 Если 4 байта представляют из себя DWORD-адрес, который лежит в диапазоне адресов сегм. данных твоего приложения => значит, очевидно, это указатель
Не факт, велика вероятность ошибки. Эти 4 байта могут быть и простым числов Integer. Где-то есть информация о переменной. Она хранится в памяти около адреса переменной. Например, размер переменной хранится, помоему, а 4-х байтах от адреса переменной назад. Тоесть отнимите от адреса переменной 4 и получите адрес, где хранится размер. Для остальной информации есть что-то подобное, но вот подробнее я уже не нашел. ![]() |
|
Создано: 24 февраля 2008 21:17 · Личное сообщение · #4 |
|
Создано: 25 февраля 2008 00:14 · Личное сообщение · #5 sibedir Мне нужно на этапе выполнения, зная лишь адресу переменной, узнать ее структуру: тип и размер. С размером все понятно. Есть SizeOf. С каких пор sizeof стала работать на этапе выполнения? Скажите, возможно ли это впринципе. Если да то, какими средствами, в каком направлении капать? Только если эта информация хранится где-то в исполняемом файле в явном виде(как например в байткоде Явы). С обычным машинным кодом это невозможно. Можно только попытаться придумать какие-то эвристики. ![]() |
|
Создано: 25 февраля 2008 08:52 · Личное сообщение · #6 |
|
Создано: 25 февраля 2008 09:14 · Личное сообщение · #7 HiEndsoft пишет: копай VirtualQuery и т.п Наврятли, HiEndsoft. В информации о виртуальном адресном пространстве не содержится данных о конкретных блоках и их назначении. Stiver пишет: С каких пор sizeof стала работать на этапе выполнения? На этапе выполнения, значит в процессе выполнения откомпелированной программы. Именно на этом этапе и работают все процедуры и функции. Акцентируя внимание на этап, я имел в веду, что на этапе программирования, написания кода, я собственными глазами могу посмотреть структуру любого типа, а значит, могу делать с этим адресным пространством все что захочу, не опасаясь негативно повлиять на работоспособность приложения. Но мне не всегда заранее известна структура типа. Если например моя функция реализована в библиотеке, которую я единажды создал, и далее использую в других приложениях, не изменяя саму библу, то мне придется программно выдерать инфу о типе данных, хранимых под определенным адресом. Я хотел написать универсальную функцию, которая по адресу сама определяла, что за данные. Пока я могу лишь определить адреса и размеры данных. Этого мне может и хватило бы, но мне мешает тот факт, что сами данные могут не хранится именно в этом адресном пространстве, а это может быть всего лишь ссылка. Так вот я и хотел найти способ, как отделить ссылки (Pointer) от непосредственно данных. Stiver пишет: Только если эта информация хранится где-то в исполняемом файле в явном виде(как например в байткоде Явы). С обычным машинным кодом это невозможно Видимо вы правы. Но всеравно, спасибо всем за уделенное время. Будут идеи пишите в эту тему, буду очень признателен. ![]() |
|
Создано: 25 февраля 2008 09:15 · Личное сообщение · #8 |
|
Создано: 25 февраля 2008 09:34 · Личное сообщение · #9 |
|
Создано: 25 февраля 2008 10:16 · Личное сообщение · #10 |
|
Создано: 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 на самом деле просто делает за тебя на этапе программирования, написания кода, я собственными глазами могу посмотреть структуру любого типа - смотрит определение. ![]() |
|
Создано: 25 февраля 2008 13:15 · Личное сообщение · #12 |
|
Создано: 25 февраля 2008 13:53 · Личное сообщение · #13 SizeOf придумана для гибкости программирования-это RT-константа. Твою задачу можно решить только написанием дизассемблера-отладчика. Константы можно попробовать выдрать ч/з PE. Зачем тебе это? При работе с API или уже с известными при дизассемблировании ф-циями можно видеть значения структур и переменных при сплайсинге и подмене адреса возврата. Кстати, например в новых msvcrt7-8, .NET и т.п. много экспортируемых структур, так что можно все о них узнать. ----- продавец резиновых утёнков ![]() |
|
Создано: 25 февраля 2008 14:23 · Личное сообщение · #14 |
|
Создано: 25 февраля 2008 16:29 · Личное сообщение · #15 |
|
Создано: 25 февраля 2008 17:14 · Личное сообщение · #16 |
|
Создано: 26 февраля 2008 06:33 · Поправил: sibedir · Личное сообщение · #17 Кажется нашел. Это действительно RTTI. Я поначалу тут и копал, но меня сбило то, что во всех источниках, которые я смотрел, говорилось лишь об информации класса из раздела published. Но как оказалось RTTI - намного белее продвинутая, хотя и недокументируемая, технология. ![]() Как закончу изучать, сразу сюда отпишусь. ![]() |
|
Создано: 27 февраля 2008 19:34 · Личное сообщение · #18 |
|
Создано: 29 февраля 2008 06:04 · Личное сообщение · #19 Короче труба. RTTI - вешь конечно хорошая. Но проблема в том, что к таким типам как Pointer или TClass методы этой технологии не подходят. А мне они ой как нужны. Выход один - нужно самому в каждом классе регистрировать каждое поле, в общем реализовать что-то типа своего RTTI. Но это уже не имеет смысла. Я с таким же успехом для каждого класса напишу процедуру сохранения, как это всегда и делается. Ну да бог с ним. Как говорится - попытка не пытка. А то, что я хотел узнать, я узнал. Всем без исключения спасибо, что пытались помочь и помогли. ![]() ![]() |
|
Создано: 29 февраля 2008 21:14 · Личное сообщение · #20 |
![]() |
eXeL@B —› Программирование —› Найти список полей класса |