所有结构成员的预处理器批处理
Preprocessor batch for all structure members
是否可以编写一个预处理器宏,为结构的所有成员自动迭代?
我有这样一个结构(从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
的所有成员进行迭代即可。
从c++14开始,是的,我们确实有(几乎所有)聚合类型的编译时反射,请参阅Antony Polukhin的magic get库(以及此cppcon演示文稿,了解其工作原理)。我认为您也可以在c++11中使用一些ABI支持。
例如,要分配给ExtU_motionCtrlRTOS_T x;
,只需编写
boost::pfr::flat_structure_tie(x) = boost::pfr::flat_structure_tie(some_unrelated_pod);
我假设成员是按顺序分配的。请注意,我使用了flattie版本,来按元素分配嵌套数组。
现在,鉴于上述情况,更明智的做法是避免像现在这样依赖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应该是一个数组,现在将获得两个偏移
没有"自动"手段,没有
不幸的是,你的结构是自动生成的。如果它们完全在你的控制之下,我建议使用这里描述的REFLECTABLE宏。
请阅读答案,也许你可以重组你的代码和/或工作流程,使其发挥作用?
相关文章:
- 错误:无效的预处理指令 #i 的意思是 #if?
- C++预处理会生成变量成员、资源库和映射
- 使用预处理指令检查是否包含标头?
- 预处理的 C/C++ 文件是否特定于计算机?
- 使用 GCC 对 C 文件进行部分预处理(不删除 "define" 指令)
- 在 CPLEX 中求解线性规划,无需剪切和预处理
- CPP -D 选项,用于预处理 Fortran 代码
- 错误:粘贴"tmp_UINT"和"+"未提供有效的预处理令牌
- 任务计划程序库的预处理不起作用 - 多定义错误
- Eclipse 问题 - 编译期间不考虑 .c 和 .cpp 文件中定义的预处理
- 使用python预处理后,C++(opencv)中的垫子类型数据与image_to_array相同
- Howo 使用 cl 预处理为 masm 组装生成一个单独的文件
- 我有一个预处理的 C/C++ 源文件 (cacti.i).如何从这个 .i 文件生成可执行二进制文件,以便我可以像 ./
- 如何使用Visual Studio C/C++编译器(cl.exe)来预处理我的objective-C代码
- 是具有预处理前分支实现的结构违反ODR
- 与不完整的Cholesky预处理的共轭梯度返回特征库的意外错误
- Visual Studio C - 无法输出预处理文件
- 在海湾合作委员会中加快宏观预处理的任何方法
- Xmllint未设置,而在路径中找不到XMLLINT;跳过XML预处理
- 当头文件被预处理时是否有一个预处理器选项显示?