Russian Qt Forum

Программирование => С/C++ => Тема начата: Cyrax от Сентябрь 11, 2006, 20:06



Название: Сделать невозможное...
Отправлено: Cyrax от Сентябрь 11, 2006, 20:06
Необходимо выполнить такой вот фокус.
Программа вызывает функцию и передаёт ей типизированный указатель. Функция принимает этот указатель как void *. Т.е. ничего не знает о типе объекта, на который указывает фактичекий параметр.
Задача функции заключается в определении типа объекта (имена классов и полей нас не интересуют, главное - структура объекта, т.е. состав и расположение полей), на который ссылается указатель.  
Функции известно всё о классах, на объекты которых может ссылаться полученный указатель.
8)
Использовать любые, даже самые извращенские способы: делать ассемблерные вставки, лезть в стек и кучу, использовать переменные окружения и т.п.


Название: Сделать невозможное...
Отправлено: Admin от Сентябрь 12, 2006, 00:20
а если просто dinamic_cast проверить указатель на
все ВОЗМОЖНЫЕ классы?


Название: Сделать невозможное...
Отправлено: joktar от Сентябрь 12, 2006, 04:21
Задача распадается на две:
- выяснить что это за класс
- выяснить его структуру(нужны как я понимаю смещения полей?)

Классы могут быть СОВСЕМ любые?(т.е. это может быть POD-тип(int/float), может быть множественное наследование и т.п. фокусы)

Исходники этих классов вообще есть?
Изменять описания тех классов что нужно обрабатывать допускается?

Если да-можно пойти по пути Qt(и MFC):все классы наследуются от OurBaseObject,
а те поля в них которые необходимо выставить на всеобщее обозрение метятся макросами(чтото вроде
DeriveClass:public OurBaseObject
{
  DECLARE_CLASS(DerivedClass,OurBaseObject)
  DECLARE_FIELD(int,IntVar);
...
}
)
Если такие описания писать не особо хочется(либо нельзя модифицировать код исходных классов) - можно опять же идти путем Qt и использовать чтото вроде Qt Meta-object compiler(который сам генерит похожий код) для создания метаклассов. Генератор метаклассов можно сделать либо на базе расуроченного moc либо использовать gccxml+свой постпроцессинг.


Название: Сделать невозможное...
Отправлено: Cyrax от Сентябрь 12, 2006, 07:16
<i>Классы могут быть СОВСЕМ любые?(т.е. это может быть POD-тип(int/float), может быть множественное наследование и т.п. фокусы)
</i>
Достаточно структур.

<i>Исходники этих классов вообще есть?
Изменять описания тех классов что нужно обрабатывать допускается?
</i>
Исходников нет.
Считаем, что всё, что нам нужно знать об этих классах, известно процедуре. Т.е. эту информацию сразу используем в процедуре в готовом виде.
Не допускается...


Название: Сделать невозможное...
Отправлено: bigirbis от Сентябрь 12, 2006, 13:42
ИМХО, удачным решением может оказаться объявление шаблонной функции, тогда никаких приведений не потребуется. Это сработает, если при вызове функции доподлинно известен тип аргумента.


Название: Сделать невозможное...
Отправлено: joktar от Сентябрь 12, 2006, 14:00
Если исходный код скомпилирован с поддержкой RTTI то я бы создал левые классы той же структуры(по условию мы знаем структуру, если в классе нет виртуальных функций,наследования,etc то структуру мы можем повторить), затем dynamic_cast'ом определял что это за класс а затем  Cоотвествующий_левый_Класс data=reinterpret_cast<соотвествующий_левый_класс>(наш_void*);

Если поддержки RTTI нет(либо эти структуры вообще берутся например из вызовов какогонибудь API) то нужен какойто метод для понимания какой конкретно класс(например у многих структур made by MS есть поле dwSize в котором хранится размер соотвествующей структуры в байтах, можно по нему определять, либо может быть что в во всех классах есть поле вроде int typeOfClass; тогда можно по нему) а затем - опять reinterpet_cast (ну или сишный кастинг).

Если нет ничего вроде dwSize/typeOfClass то я бы пытался определять какого именно типа этот класс кастингом во все возможные классы подряд и проверкой логической корректности полей(то еще занятие. причем без 100% гарантии успеха), по условию сведения о возможных типах и значениях полей у нас ведь есть?(если нет-IDA в руки и получить эти данные)


p.s.Если не секрет-нельзя ли побольше о специфике задачи?Откуда берутся эти структуры(какой то API,просто внутренние структуры какой то проги,или что)?Нам их только читать или еще и модифицировать?Они точно пишутся из кода на C/C++(а не на Python/C# допустим, что _может_ упростить задачу )?
Примеры возможных описаний структуры структур тоже бы не помешал.


Название: Сделать невозможное...
Отправлено: bigirbis от Сентябрь 12, 2006, 14:27
Если понадобится передавать в функцию встроенные типы, такой подход предоставит программисту слишком большое количество геморроя.