Следуйте за десятым законом Greenspun, и вам хорошо идти: просто реализуйте специальную, неформально указанную, с ошибкой, медленную реализацию половины Common Lisp. Выберите половину, которая поддерживает реализацию рефлексии. :)
Или вот идея:
Включите файлы карты (и, возможно, генерации сборки) в сборки. Внедрение приложения, которое генерирует код для создания динамической библиотеки. Вы должны иметь возможность получить всю статическую информацию (имена методов, параметры, типы и т. Д.) Об классах из источника или одного из артефактов сборки. Используя карту или сборку, вы сможете найти адреса функций, смещения указателей виртуальных функций, адреса глобальных переменных, смещения переменных, информацию о стеке и регистровые распределенные переменные и т. Д. И т. Д. Из этой информации создайте библиотеку, содержащую вызовы для получения всей этой информации, передав имена типов, указатели, имена функций и т. Д.
Теперь, на C++, напишите библиотеку, содержащую функции и макросы, которые позволят вам поместить уникальный идентификатор, который будет быть скомпилированы в код для идентификации запуска функций, всех вызовов отражения, смещения EIP при вызовах отражения и т. д. Используйте встроенные макросы сборки в соответствующих местах, которые оставляют место, где это необходимо, с помощью NOP, чтобы приложить несколько инструкций, если вам нужно, как правило, сразу после Я БЫ. Кроме того, предоставляйте функции библиотеки моста, которые позволят функциональности отражения либо обрабатывать то, что она может встроить (например, получить адрес функции), либо делать вызовы в динамическую библиотеку, построенную на этапе после сборки.
Наконец, напишите пост-пост сборщик рефлексии. Я предлагаю «kniltsoPostlink», но это зависит от вас. На этом шаге найдите свои уникальные идентификаторы (я упомянул, чтобы облегчить вам, возможно, вы должны сделать идентификаторы идентификаторов ID, чтобы вы могли искать их в двоичном формате?), И везде, где идентификатор маркирует вызов отражения функции, или определение класса и т. д., размещайте там достаточно данных (в формате, который вы можете легко определить точно во времени, когда вы пишете библиотеку отражателя), а затем в идентификаторе перед вызовом библиотеки рефлектора перепишите вызов так, чтобы он извлекает нужные ему параметры из этих битов данных или просто кладет туда биты данных, если это применимо, я не могу знать заранее, но, как вы его пишете, эти маленькие детали просто выскочат на вас.
В любом случае, я знаю, что не получил много кода, и на самом деле я намереваюсь начать проект по этому поводу, когда у меня будет достаточно свободного времени. Я имею в виду, что каждая маленькая часть должна быть очень простой, так как вы делаете это постепенно, каждая маленькая часть должна стать ясной, если вы будете следовать изложенным здесь инструкциям. Возможно, что некоторые из них на самом деле будут еще проще, чем я описал здесь, потому что это был худший сценарий. Вы даже можете уйти, даже не переписывая код на звонок рефлектора; просто размещение данных в соответствующих точках может позволить библиотеке вытягивать эти биты по мере необходимости без дополнительной информации.
Я очень рад, что вы спросили; Я сейчас очень занят, но если вы получите ночь бесплатно, я думаю, что это будет хороший старт в первой версии, и я буду рад, если смогу.
;)
Не будет ли это стоить больше, чем RTTI, и что это даст? – Mark
Жесткий. Вы не можете маршалировать компилятор для генерации метаданных, которые вам нужны из исходного кода. RTTI крайне неадекватен. Вам нужно будет написать собственный синтаксический анализатор языка C++. Это было сделано ... –
@nobugz: Конечно, люди написали свои собственные сиквел C++. Это очень далеко не тривиально. C++ - очень простая реальная боль для синтаксического анализа. –