Если вы ищете относительно простое отражение C ++ - я собрал из различных источников макро / определения и прокомментировал их, как они работают. Вы можете скачать заголовок
файлы отсюда:
https://github.com/tapika/TestCppReflect/blob/master/MacroHelpers.h
набор определений, плюс функциональность поверх него:
https://github.com/tapika/TestCppReflect/blob/master/CppReflect.h
https://github.com/tapika/TestCppReflect/blob/master/CppReflect.cpp
https://github.com/tapika/TestCppReflect/blob/master/TypeTraits.h
Пример приложения также находится в репозитории git, здесь:
https://github.com/tapika/TestCppReflect/
Я частично скопирую это здесь с объяснением:
#include "CppReflect.h"
using namespace std;
class Person
{
public:
// Repack your code into REFLECTABLE macro, in (<C++ Type>) <Field name>
// form , like this:
REFLECTABLE( Person,
(CString) name,
(int) age,
...
)
};
void main(void)
{
Person p;
p.name = L"Roger";
p.age = 37;
...
// And here you can convert your class contents into xml form:
CStringW xml = ToXML( &p );
CStringW errors;
People ppl2;
// And here you convert from xml back to class:
FromXml( &ppl2, xml, errors );
CStringA xml2 = ToXML( &ppl2 );
printf( xml2 );
}
REFLECTABLE
define использует имя класса + имя поля с offsetof
- чтобы определить, в каком месте в памяти находится конкретное поле. Я постарался максимально приблизиться к терминологии .NET, но C ++ и C # различны, поэтому это не 1 к 1. Вся модель отражения C ++ находится в классах TypeInfo
и FieldInfo
.
Я использовал pugi xml parser для извлечения демонстрационного кода в xml и восстановления его из xml.
Таким образом, вывод, созданный демонстрационным кодом, выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<People groupName="Group1">
<people>
<Person name="Roger" age="37" />
<Person name="Alice" age="27" />
<Person name="Cindy" age="17" />
</people>
</People>
Также возможно включить поддержку любых сторонних классов / структур через класс TypeTraits и частичную спецификацию шаблона - чтобы определить свой собственный класс TypeTraitsT, аналогично CString или int - см. Пример кода в
https://github.com/tapika/TestCppReflect/blob/master/TypeTraits.h#L195
Это решение применимо для Windows / Visual studio. Можно портировать его на другие ОС / компиляторы, но этого еще не сделали. (Спросите меня, действительно ли вам нравится решение, я могу вам помочь)
Это решение применимо для сериализации одним выстрелом одного класса с несколькими подклассами.
Если, однако, вы ищете механизм для сериализации частей класса или даже для контроля над тем, какие функциональные возможности вызывает отражение, вы можете взглянуть на следующее решение:
https://github.com/tapika/cppscriptcore/tree/master/SolutionProjectModel
Более подробную информацию можно найти на YouTube видео:
C ++ Тип выполнения Отражение
https://youtu.be/TN8tJijkeFE
Я пытаюсь немного глубже объяснить, как будет работать отражение c ++.
Пример кода будет выглядеть, например, так:
https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/testCppApp.cpp
c.General.IntDir = LR"(obj\$(ProjectName)_$(Configuration)_$(Platform)\)";
c.General.OutDir = LR"(bin\$(Configuration)_$(Platform)\)";
c.General.UseDebugLibraries = true;
c.General.LinkIncremental = true;
c.CCpp.Optimization = optimization_Disabled;
c.Linker.System.SubSystem = subsystem_Console;
c.Linker.Debugging.GenerateDebugInformation = debuginfo_true;
Но каждый шаг здесь фактически приводит к вызову функции
Использование свойств C ++ с __declspec(property(get =, put ... )
.
, который получает полную информацию о типах данных C ++, именах свойств C ++ и указателях экземпляров классов в форме пути, и на основе этой информации вы можете генерировать xml, json или даже сериализовать эту информацию через Интернет.
Примеры таких виртуальных функций обратного вызова можно найти здесь:
https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/VCConfiguration.cpp
См. Функции ReflectCopy
и виртуальные функции ::OnAfterSetProperty
.
Но поскольку тема действительно продвинутая, я рекомендую сначала проверить видео.
Если у вас есть идеи по улучшению, не стесняйтесь связаться со мной.