19

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

您是否知道任何支持反射和属性容器的 C++开源库,特别是:

  • 通过宏定义 RTTI 和属性
  • 通过代码访问 RTTI 和属性
  • 属性的自动序列化
  • 监听属性修改(例如 OnValueChanged)
4

8 回答 8

13

有一个使用完全不同的方法在 C++ 中提供反射的新项目:CAMPhttps://github.com/tegesoft/camp

CAMP 不使用预编译器,classes/properties/functions/... 是使用类似于 boost.python 或 luabind 的语法手动声明的。当然,如果他们愿意,人们可以使用像 gccxml 或 open-c++ 这样的预编译器来生成这个声明。

它仅基于纯 C++ 和 boost 头文件,并且由于模板元编程的强大功能,它支持任何类型的可绑定实体(例如,继承和奇怪的构造函数不是问题)。

它是根据 MIT 许可证(以前的 LGPL)分发的。

于 2010-06-16T08:24:08.247 回答
12

这就是当 C++ 遇到反射时你得到的:

C++ 遇到反射

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

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

于 2008-09-17T22:09:55.260 回答
6

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

XRTTI

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

开放C++

OpenC++ 是 C++ 前端库(lexer+parser+DOM/MOP)和源到源的翻译器。OpenC++ 支持开发 C++ 语言工具、扩展、特定领域的编译器优化和运行时元对象协议。

于 2008-09-17T22:11:01.560 回答
4

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

我现在使用的这种公开成员的方法非常轻量级,例如,您可以探索一个用于序列化的类或将所有名为“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 << " ";
     }
}
于 2010-03-21T05:09:21.177 回答
3

这通常是 C++ 语言的一个臭名昭著的弱点,因为需要标准化以使反射实现可移植和有价值的东西不是标准的。我想到了调用约定、对象布局和符号修饰,但还有其他一些。

缺乏来自标准的方向意味着编译器实现者会做一些不同的事情,这意味着很少有人有动力去写一个可移植的反射库,这意味着需要反射的人重新发明轮子,但只是够用了他们需要什么。这种情况会无限发生,我们就在这里。

于 2008-09-17T22:00:06.890 回答
3

这个也看了一会儿。当前最简单的解决方案似乎是BOOST_FUSION_ADAPT_STRUCT。实际上,一旦有了库/头文件,您只需将结构字段添加到 BOOST_FUSION_ADAPT_STRUCT() 宏中,如代码的最后一段所示。是的,它有许多其他人提到的限制。而且它不直接支持听众。

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

  • CAMP 和 XRTTI/gccxml,但是两者似乎都是将外部工具依赖项引入项目的障碍。
  • 几年前,我使用 perl c2ph/pstruct从 的输出中转储元信息,gcc -gstabs虽然它对我来说非常有效,但它的侵入性较小,但需要更多的工作。

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

于 2012-09-06T07:56:40.913 回答
2

不是通用的,但 QT 通过元编译器支持这一点,并且是 GPL。我与 QT 人员交谈的理解是,纯 C++ 无法做到这一点,因此需要 moc。

于 2008-09-17T21:53:47.577 回答
0

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

于 2014-03-12T12:25:14.820 回答