简体   繁体   中英

How to get a property name and offset in a class at compile time or runtime?

I have a class named SoftInfo.

class SoftInfo
{
  public:

    std::string m_strSoftName;

    std::string m_strSoftVersion;

    std::string m_strInstallLocation;
}

I want to export it to lua in a c++ program via sol3. I write something like this and I can use it in lua world. However, there are something unconvenient. I need to write the name and offset of any property of class SoftInfo. When I change the property name in SoftInfo, I also need to change the name in function Export. Besides, if the number of properties of SoftInfo is too large, it will be very hard to write the Export function manually.

void Export(lua_state _state)
{
 _state.new_usertype<SoftInfo>("SoftInfo", 
   "m_strSoftName",&SoftInfo::m_strSoftName,
"m_strSoftVersion",&SoftInfo::m_strSoftVersion,
"m_strInstallLocation",&SoftInfo::m_strInstallLocation);
}

or

void Export(lua_state _state)
{
        sol::usertype<SoftInfo> usertype_table = _state.new_usertype<SoftInfo>("SoftInfo");
        usertype_table["m_strSoftName"] = &SoftInfo::m_strSoftName;
        usertype_table["m_strSoftVersion"] = &SoftInfo::m_strSoftVersion;
        usertype_table["m_strInstallLocation"] = &SoftInfo::m_strInstallLocation;
}

I wonder is there a way to avoid these complicated work like macro that I can wirte something like this? If other solution can reduce the complicated manual working, it is not limited to the solution pattern I supplied below.

class SoftInfo
{
  public:
    //Macro or something defined here
    std::string m_strSoftName;

    std::string m_strSoftVersion;

    std::string m_strInstallLocation;
}

void Export(lua_state _state)
{
 sol::usertype<ship> usertype_table = _state.new_usertype<SoftInfo>("SoftInfo");
 for(auto [properties,offset]:Func(SoftInfo))
     usertype_table[properties] = offset;
}

What you're asking for is called static reflection. Unfortunately, C++ doesn't have that. However, with boost describe , you may get quite close

#include<boost/describe.hpp>

BOOST_DESCRIBE_STRUCT(SoftInfo, (),
    (m_strSoftName,
     m_strSoftVersion,
     m_strInstallLocation))

void Export(lua_state _state)
{
    sol::usertype<SoftInfo> usertype_table = _state.new_usertype<SoftInfo>("SoftInfo");
    using namespace boost::describe;
    using M = describe_members<SoftInfo, mod_any_access>;
    boost::mp11::mp_for_each<M>([&](auto d){
        using D = decltype(d);
        usertype_table[D::name] = D::pointer;
    });
}

BOOST_DESCRIBE_STRUCT has to be maintained manually by filling in all the members but Export will be automatically implemented.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM