所有结构成员的预处理器批处理

时间:2017-11-14 13:37:11

标签: c++ c-preprocessor

是否可以编写一个自动迭代结构的所有成员的预处理器宏?

我有这样的结构(从Simulink模型自动生成):

typedef struct {
  real_T driveStatusword;
  real_T posSensor[2];
  real_T softAbortDemand;
} ExtU_motionCtrlRTOS_T;

和类似的一样:

struct CoreInputOffsets
{
    uint32_t driveStatusword;
    uint32_t posSensor;
    uint32_t softAbortDemand;
};

我想做这样的操作:

void getCoreInputOffsets(CoreInputOffsets* pCoreInputOffsets)
{
    pCoreInputOffsets->driveStatusword = offsetof(ExtU_motionCtrlRTOS_T, driveStatusword);
    pCoreInputOffsets->posSensor = offsetof(ExtU_motionCtrlRTOS_T, posSensor);
    pCoreInputOffsets->softAbortDemand = offsetof(ExtU_motionCtrlRTOS_T, softAbortDemand);
}

但是,每次结构更改时都不必编辑此函数,通过迭代CoreInputOffsets的所有成员。

2 个答案:

答案 0 :(得分:3)

来自c ++ 14,是的,我们确实有(几乎所有)聚合类型的编译时间反映,请参阅 Antony Polukhin ' magic get library(和{{3} } cppcon演示文稿,了解它是如何工作的)。我认为你也可以在c ++ 11中使用ABI支持它。

例如,要分配给ExtU_motionCtrlRTOS_T x;,您只需编写

即可
boost::pfr::flat_structure_tie(x) = boost::pfr::flat_structure_tie(some_unrelated_pod);

我假设成员按顺序分配。请注意,我使用了 flat tie版本,以元素方式分配嵌套数组。

现在,鉴于上述情况,避免依赖offsetof()会更加明智,因为你现在正在做,只是利用相关操作的所有编译时信息(这也可能会给你更快的代码)

无论如何,如果您仍想获得偏移量,您的代码的逐字转录可能如下所示:

#include <boost/pfr/flat/core.hpp>

struct CoreInputOffsets
{
    uint32_t driveStatusword;
    uint32_t posSensor[2];
    uint32_t softAbortDemand;
};

template <typename T,std::size_t... Is>
void assignOffsets( CoreInputOffsets& offsets, std::index_sequence<Is...> )
{
  T t;
  (( boost::pfr::flat_get<Is>(offsets) = reinterpret_cast<char*>(&boost::pfr::flat_get<Is>(t)) - reinterpret_cast<char*>(&boost::pfr::flat_get<0>(t)) ), ...);
}

template <typename T>
void assignOffsets( CoreInputOffsets& offsets )
{
  assignOffsets<T>( offsets, std::make_index_sequence< boost::pfr::flat_tuple_size<T>::value >{} );
}

void getCoreInputOffsets(CoreInputOffsets* pCoreInputOffsets)
{
  assignOffsets<ExtU_motionCtrlRTOS_T>( *pCoreInputOffsets );
}

使用警告

  • 这是c ++ 17(你可以使它符合c ++ 14)
  • 获取实际偏移量的代码需要一个虚拟ExtU_motionCtrlRTOS_T;这不是什么大不了的,因为你只需要分配一次,我想
  • 通过指针减法获取实际偏移量的代码在标准方面给出了未定义的行为,您需要验证它对您的平台是否合法
  • CoreInputOffsets :: posSensor应该是一个数组,现在将两个偏移

答案 1 :(得分:1)

没有“自动”方式,没有。

不幸的是,您的结构会自动生成。如果它们完全由你完全控制,我会推荐像here所述的REFLECTABLE宏。

请阅读该答案,也许您可​​以重组您的代码和/或工作流程以使其有效?