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

使用boost传递反射::hana

  •  2
  • Stewart  · 技术社区  · 7 年前

    有没有办法获取表示 boost::hana 我可以传递并存储在地图/数据库中的结构反射?

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

    在一个示例中,我可以很容易地反映出以下结构:

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

    我的库将创建 Car 并且需要通过入口点提供。这意味着它需要坚持从my environment 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;
    });
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Jason Rice    7 年前

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

    正如评论中所建议的, 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';
      }
    }