Войти
ПрограммированиеФорумОбщее

Автоматическая рефлексия на C++

Страницы: 1 2 Следующая »
#0
19:33, 30 дек. 2010

Добрый день.

Хочу узнать актуальная ли это тема и не изобретаю ли я велосипед.
Я знаю что есть boost::serialization, но там все таки нужно дополнительно описывать сериализацию помимо объявления самих членов структур. Мне стала интересна именно принципиальная возможность на С++ полностью автоматизировать генерацию метаданных для любой структуры/класса и функции сериализации для них.
Я написал небольшой макрос и шаблон на пару строк который позволяет делать так:

struct_( SomeItem )
  _( int,   Index );
  _( char*, Name );
  _( int,   Damage );
end_;

SomeItem Items[] = { 
  { 1, "Sword"  , 35 },
  { 2, "Axe"    , 60 },
  {-1, 0/*"No item"*/  , 0  },
};

ArrayOfStructToTextOut(Items);
Выводятся все объекты в массиве с автоматическим перечислением их типа, всех их полей (значений и типов). Если меняется описание структуры ничего дописывать и менять не надо. К структуре автоматически добавляются только пара статических констант и к каждому полю шаблон статической функции класса возращающей константные данные о поле. При оптимизации это вообще все выкидывается компилятором, остается только глобальный константный массив со всеми данными о сериализуемых классах, который можно перебирать в цикле, хешировать, создавать любые объекты по строковому имени типа в рантайме и т.п.

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


#1
19:44, 30 дек. 2010

DDragon
Не знаю, что именно ты хочешь получить, но рекомендую посмотреть на boost::mpl.

#2
19:52, 30 дек. 2010

Я хочу получить простую сериализацию, проще чем в бусте, и без применения буста. Я оттуда беру полезное небольшое разное, но сам буст к проекту подключать не хочу.

#3
19:55, 30 дек. 2010

Есть gccxml - он выдает в виде xml полную метаинформацию. Правда файл зачастую получается очень здоровый, но тем не менее данный тул используется например для генерации байндингов для питона и руби

А нормально сделать это средствами С++ просто нельзя - язык вообще не поддерживает метаинформацю (убогий RTTI можно не считать)

#4
20:00, 30 дек. 2010

Ну что значит нельзя, я же сделал (без применения RTTI, STL и boost). Возможно это тоже всё убого, но работает. Средствами самого языка, без внешних утилит. Правда многие мне говорят что макросы это не средство языка и их применять нельзя для генерации кода, я правда так ни от кого пока не добился внятного объяснения почему. Может быть их в следующем стандарте запретят?

#5
20:06, 30 дек. 2010

ЗЫ. Посмотрел mpl, забористая штука. Изучу поплотнее, может что полезное найду. Хотя опять же, многоуровневые шаблоны которые надо писать вручную, обязательные конструкторы. Это не совсем то чего я хотел.

#6
20:10, 30 дек. 2010

DDragon
Микрософт, Эпики и остальные используют для этих целей макросы, почему нам нельзя? Альтернатива только кодогенерация, что лично мне кажется неудобным. Практические примеры в GPGems первых выпусков.

#7
22:48, 30 дек. 2010

рефлекшн - это не только сериализация/десериализация - и нужен-ли он для игр тот еще вопрос.
а про сериализацию есть много где.

#8
1:00, 31 дек. 2010

Мы решили вопрос кодогенерацией. Т.е, парсим потихоньку C++-сырец и генерим
а) биндинг методов, пропертей, полей
б) экспорт всего добра в C++/CLI
в) экспорт всего в скрипт (пока в свой, но можно и для boost::python, tolua++ или ещё чего)
г) код для сериализации

Проблемы топик-стартера с тем, что boost::mpl и boost::serialization требует немало рукописной разметки, хорошо известны и их решают во всех практически фреймворках. Тот же Qt со слотами, сигналами и пропертями использует MOC для серьёзной обработки кода. UCC (из UnrealEngine) по C++'у генерит врапперы для их виртуальной машины. И т.д., и т.п.

GccXml как вариант несамописного фронт-энда для парсинга C++-кода тоже неплох, по-моему, только Kitware на него забила уже давно, к сожалению. Ну и великоват он, как ни крути.

>> А нормально сделать это средствами С++ просто нельзя - язык вообще не поддерживает метаинформацю (убогий RTTI можно не считать)
Это точно, и тем не менее, "ёжики плакали, но продолжали грызть кактус" :)

#9
1:27, 31 дек. 2010

Vinil
> UCC (из UnrealEngine) по C++'у генерит врапперы для их виртуальной машины
Только наоборот. Помеченные нативные классы и фрагменты СПП кода из скрипта сливаются в хидер. Затем билдится движок - а это долго.

#10
10:23, 31 дек. 2010

http://www.gamedev.ru/code/articles/attributes_in_cpp

ну и на рсдн есть пара статей на которые я опирался

http://rsdn.ru/article/xml/xmlcpp.xml
http://rsdn.ru/article/files/Classes/Serialization2.xml
http://rsdn.ru/article/cpp/cpp_metadata.xml

там нечто похожее на твой велосипед есть. без заморочек.

#11
10:52, 31 дек. 2010

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

#12
11:22, 31 дек. 2010

DDragon
> Ну что значит нельзя, я же сделал (без применения RTTI, STL и boost). Возможно
> это тоже всё убого, но работает. Средствами самого языка, без внешних утилит.

ты сэмулировал сугубо то, что нужно тебе, при помощи макросов (считай тот же кодогенератор, только встроенный в компилятор:) ).
А реально на уровне языка рефлексии не существует.

P.S.: я не к тому, что ты какое-то УГ сделал :) Тебе подходит и нравится - великолепно. Я к тому, что фраза steps3d про то, что этого в языке нет и нормально это не сделать, абсолютно верна.

#13
16:09, 5 янв. 2011

Нашел такое чудо:
https://dev.tegesoft.com/projects/camp

Кто пробовал, какие впечатления?

Пример из их wiki:

 1 // a dummy class that we're going to bind
 2 class MyClass : public MyBaseClass
 3 {
 4 public:
 5     MyClass(int, float);
 6     std::string prop;
 7     void func();
 8 };
 9 
10 // the CAMP binding of the class
11 camp::Class::declare<MyClass>("MyClass")
12     .base<MyClassBase>()
13     .constructor2<int, float>()
14     .property("prop", &MyClass::prop)
15     .function("func", &MyClass::func)
16     ;

#14
16:20, 5 янв. 2011

Те же яйца вид сбоку. Опять надо вручную описывать метаклассы и разворачивать кучу шаблонов.
Один плюс, универсальность.

Цитата:
"It is important to note that creating a meta-class is an expensive operation for the compiler, and it can be very slow to compile (because of the lot of templates involved). It is thus recommended to put a meta-class declaration in a file separated from the class implementation, so that you don't need to recompile the meta-class if you change the class implementation."

Мне нравится мой метод, ничего нигде не надо описывать вообще. Достаточно объявления самого класса.

Страницы: 1 2 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.