2

有没有办法获得一个代表boost::hana结构反射的对象,我可以传递并存储在地图/数据库中?

我正在环境和作为插件动态加载的共享库之间创建一个接口。我需要反映库中使用的一些数据结构,以便用户可以在运行时使用环境导航这些结构。

在一个例子中,我有这个结构,我可以很容易地反映:

struct Car {
    BOOST_HANA_DEFINE_STRUCT(Car, 
        (std::string, brand),
        (std::string, model)
    );
};

我的库将创建一个实例,Car并且需要通过入口点使其可用。这意味着它需要坚持从我的环境 SDK 中实现一个基类,它看起来有点像这样:

template<class SharedStructureType>
class LibraryAPI
{
public:
    virtual void run() = 0; // Some entrypoint called by the environment

    ReflectedType GetReflection()
    {
        return to_reflection(m_sharedData);
    }

protected:
    SharedStructureType m_sharedData;

private:
    ReflectedType to_reflection(SharedStructureType);
};

我的问题是我不确定如何实施LibraryAPI::to_reflection.

当使用 boost::hana 反射结构时,我希望看到创建的一些对象或成员代表反射规则,这就是我希望通过界面传递的内容。但是,调试器没有显示类似的内容。

我怀疑这一切都在编译时解析的巨型模板中得到了解决。但是,我的环境和库不会同时编译,所以这让事情变得更加复杂。

有没有办法获得一个代表 boost::hana 结构反射的对象,我可以传递并存储在地图/数据库中?

- - - - - - - -编辑 - - - - - -

我并不关心取消引用数据,而是关心知道库使用的每个成员的名称、偏移量和大小。这将让我使用环境根据配置在库之间映射数据,而无需在库之间共享头文件。我可能会在反射中添加类型作为在实际执行之前验证 memcpy 的一种方式。

不幸的是,在这种情况下,当我在调试器中运行它时bmw.brand,永远不会占用相同的内存。boost::hana::second(pair)

Car bmw{"BMW", "Z3"};
boost::hana::for_each(bmw, [&](auto pair) {
    if(&bmw.brand == &boost::hana::second(pair)
        // We never get here
        int i;
});
4

1 回答 1

1

直接折叠结构时得到的对的问题是它们在第二部分中包含成员的副本,这就是为什么它们不占用与实例相同的内存的原因。

正如评论中所建议的,hana::accessors, 折叠成对,其中包含名称和一个函数,该函数接受实例并返回对相应成员的引用。

也许这接近你想要做的事情:

#include <array>
#include <boost/hana.hpp>
#include <iostream>
#include <string>
#include <vector>

namespace hana = boost::hana;

struct Car {
  BOOST_HANA_DEFINE_STRUCT(Car,
    (std::string, brand),
    (std::string, model),
    (std::array<char, 4>, year)
  );
};

struct member_meta
{
  std::string name;
  std::size_t offset;
  std::size_t size;
};

int main() {
  Car bmw{"BMW", "Z3", {'2', '0', '1', '0'}};
  std::vector<member_meta> bmw_meta{};

  hana::for_each(hana::accessors<Car>(), [&](auto pair)
  {
    bmw_meta.push_back(member_meta{
      std::string(hana::to<char const*>(hana::first(pair)))
    , reinterpret_cast<size_t>(&hana::second(pair)(bmw)) - reinterpret_cast<size_t>(&bmw)
    , sizeof(hana::second(pair)(bmw))
    });
  });

  for (auto const& x : bmw_meta)
  {
    std::cout << x.name << ' ' << x.offset << ' ' << x.size << '\n';
  }
}
于 2018-01-19T06:18:54.047 回答