代码之家  ›  专栏  ›  技术社区  ›  Fabian

C++的属性库和反射库?

  •  15
  • Fabian  · 技术社区  · 18 年前

    大多数成熟的C++项目似乎都有自己的项目。 反射与属性系统 ,即定义可以通过字符串访问并自动序列化的属性。至少我参加过的许多C++项目似乎 重新改造车轮 .

    你知道吗 良好的开源库 对于支持反射和属性容器的C++,具体地说:

    • 通过宏定义rtti和属性
    • 通过代码访问rtti和属性
    • 属性自动序列化
    • 监听属性修改(例如onValueChanged)
    8 回复  |  直到 18 年前
        1
  •  5
  •   Carl Seleborg    18 年前

    你可以看看下面的两个工具。我从来没有用过它们,所以我不能告诉你它们有多实用。

    XRTTI :

    XRTI是一种工具和附带的C++库,它扩展了C++的标准运行时类型系统,以提供更丰富的关于类和方法的反射信息,以操作这些类及其成员。

    OpenC++ :

    OpenC++是C++前端库(Lister-+ PalSe+DOM/MOP)和源到源转换程序。OpenC++允许开发C++语言工具、扩展、特定于域的编译器优化和运行时元对象协议。

        2
  •  11
  •   Tim Cooper    14 年前

    这就是C++遇到反射时所得到的结果:

    C++ meets Reflection

    无论您选择什么,它都可能有可怕的宏、难以调试的代码或奇怪的构建步骤。我见过一个系统从devstudio的pdb文件自动生成序列化代码。

    不过,说真的,对于小项目来说,编写保存/加载函数(或者使用流式操作符)会更容易。事实上,这对大型项目也适用——很明显,如果结构发生变化,通常需要更改代码。

        3
  •  11
  •   Nick    10 年前

    有一个新的项目在C++中用一种完全不同的方法提供了反映: 营地 . https://github.com/tegesoft/camp

    camp不使用预编译器,类/属性/函数。使用类似于boost.python或luabind的语法手动声明。当然,如果愿意的话,人们可以使用像gcXML或open-c++这样的预编译程序来生成这个声明。

    它只基于纯C++和Boost标头,并且得益于模板元编程的能力,它支持任何类型的可绑定实体(例如,继承和奇怪的构造函数不是问题)。

    它是根据麻省理工学院的许可证(以前是LGPL)分发的。

        4
  •  4
  •   Matthew Herrmann    16 年前

    我看这些东西看了很长一段时间,但它们往往很重。它们可能会阻止您使用继承,或者使用奇怪的构造函数等,最终它们会成为太多的负担而不是方便。

    这种公开我现在使用的成员的方法非常轻量级,可以让您探索一个用于序列化的类,或者将所有名为“x”的字段设置为0。它也是静态确定的,所以非常快。无需担心库代码或代码生成层会干扰构建过程。它一般化为嵌套类型的层次结构。

    使用一些宏设置编辑器,以自动编写其中的一些内容。

    struct point
    {
         int x;
         int y;
    
         // add this to your classes
         template <typename Visitor>
         void visit(Visitor v)
         {
             v->visit(x, "x"); 
             v->visit(y, "y");
         }
    };
    
    
    /** Outputs any type to standard output in key=value format */
    struct stdout_visitor
    {
         template <typename T>
         void visit(const T& rhs)
         {
             rhs.visit(this);
         }
    
         template <typename Scalar>
         void visit (const Scalar& s, const char* name)
         {
              std::cout << name << " = " << s << " ";
         }
    }
    
        5
  •  3
  •   Community Mohan Dere    9 年前

    也看了一会儿。目前最简单的解决方案似乎是 BOOST_FUSION_ADAPT_STRUCT . 实际上,一旦您有了库/头,您只需要将结构字段添加到boost-fusion-adapt-struct()宏中,就像 the last segment of the code shows .是的,它有许多其他人提到的限制。它不直接支持听众。

    我研究的其他有希望的解决方案是

    • 然而,camp和xrti/gccxml似乎都是将外部工具依赖性引入项目的障碍。
    • 几年前我用过Perl c2ph / pstruct 从的输出中转储元信息 gcc -gstabs 虽然对我来说效果很好,但这并不是什么干扰,但需要做更多的工作。

    关于boost/uuucxa方法,一旦您了解了所有的小细节,添加/更改结构或字段就很容易维护了。我们目前使用它在dbus上构建一个自定义类型绑定层,序列化API并隐藏托管对象服务子系统的传输/rpc详细信息。

        6
  •  2
  •   Martin Beckett    18 年前

    不是一般的,但qt通过一个元编译器支持这一点,并且是gpl。 我与QT人的理解是,这是不可能的纯C++,因此需要的MOC。

        7
  •  2
  •   Ben Collins    11 年前

    这是C++语言的一个臭名昭著的弱点,因为需要进行标准化以使反射实现轻便和有价值的东西不是标准的。人们会想到调用约定、对象布局和符号管理,但也有其他一些。

    缺乏标准的指导意味着编译器的实现者会做一些不同的事情,这意味着很少有人有动机编写一个可移植的反射库,这意味着需要反射的人会重新发明轮子,但只会满足他们的需要。这种情况发生了 无穷大 我们到了。

        8
  •  0
  •   Jen    12 年前

    自动反省/反思工具包。使用类似qt的元编译器,并将元信息直接添加到对象文件中。直观易用。没有外部依赖项。甚至允许自动反射std::string,然后在脚本中使用它。请访问 IDK