前言
想利用模板编程进行编译期计算,想先判断主机字节序然后利用std::enable_if(C++17使用if constexpr)根据字节序是大端还是小端来判断是否进行字节序转换。但第一步编译期判断字节序不成功,因为union类型不能constexpr, 起对成员的选择访问是运行时的;而又不想运行时判断,所以要用其它方法代替。首先gcc编译器是有定义宏,考虑到平台扩展性还是选用了cmake的功能。
另外我做的是本机字节序往网络字节序的互转,因此只有判断是否是大端字节序,如果本机是大端则直接return,本机是小端则转换。
cmake字节序判断
cmake提供了判断字节序的功能,在cmake 3.20之前是TestBigEndian,之后由CMAKE_BYTE_ORDER替代,官方文档:
TestBigEndian
Deprecated since version 3.20: Supserseded by the CMAKE_BYTE_ORDER variable.
Check if the target architecture is big endian or little endian.
test_big_endian
test_big_endian()
Stores in variable either 1 or 0 indicating whether the target architecture is big or little endian.
用法如下:
if (CMAKE_CXX_BYTE_ORDER STREQUAL "BIG_ENDIAN")
set(IS_BIG_ENDIAN_TARGET 1)
else()
set(IS_BIG_ENDIAN_TARGET 0)
endif()
else()
include(TestBigEndian)
test_big_endian(BIG_ENDIAN)
set(IS_BIG_ENDIAN_TARGET ${BIG_ENDIAN})
endif()
然后利用configure_file把IS_BIG_ENDIAN_TARGET传入代码中,或用add_definition(-DIS_BIG_ENDIAN_TARGET=1(or 0))文章来源:https://www.toymoban.com/news/detail-440426.html
configure_file(${PROJECT_SOURCE_DIR}/include/common/config.h.in
${PROJECT_BINARY_DIR}/include/common/config.h)
# 注意后面要target_include_directories里指定这个路径
// config.h.in
#ifndef CONFIG_H
#define CONFIG_H
#ifndef IS_BIG_ENDIAN_TARGET
#define IS_BIG_ENDIAN_TARGET @DIS_BIG_ENDIAN_TARGET@
#endif
#endif
模板编程进行字节序转换
template <class T>
static std::enable_if_t<!IS_BIG_ENDIAN_TARGET && (sizeof(T) > 1), void>
AdjustEndianness(T& value) {
uint8_t* value_begin = reinterpret_cast<uint8_t*>(&value);
std::reverse(value_begin, value_begin + sizeof(T));
}
template <class T>
static std::enable_if_t<IS_BIG_ENDIAN_TARGET || (sizeof(T) == 1), void>
AdjustEndianness(T& value) {
return;
}
template <class T>
static void AdjustVarsEndianness(T&& value) {
AdjustEndianness(std::forward<T>(value));
}
template <class T, class ...ArgTypes>
static void AdjustVarsEndianness(T&& value, ArgTypes&&... args) {
AdjustEndianness(std::forward<T>(value));
AdjustVarsEndianness(std::forward<ArgTypes>(args) ...);
}
这里只有在本机字节序和网络字节序不一致且T的size大于1时才转换字节序,因为我这个场景时通过网络发送信息,保证client和server端解析不会出错文章来源地址https://www.toymoban.com/news/detail-440426.html
到了这里,关于利用cmake和模板编程进行字节序转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!