如何在编译时计算复杂的函数?

问题描述 投票:0回答:1

我需要获取小端二进制数据,因此在大端计算机上,我通过这样做将其转换为小端

bool IsBigEndian() {
  int i = 1;

  return ((*reinterpret_cast<uint8_t*>(&i)) == 0);
}
uint32_t Reverse(uint32_t value) {
  uint32_t result;
  uint8_t* pointer_to_result = reinterpret_cast<uint8_t*>(&result);
  uint8_t* pointer_to_value = reinterpret_cast<uint8_t*>(&value);
  pointer_to_result[0] = pointer_to_value[3];
  pointer_to_result[1] = pointer_to_value[2];
  pointer_to_result[2] = pointer_to_value[1];
  pointer_to_result[3] = pointer_to_value[0];
  return result;
}
void WriteInLittleEndian(std::ofstream& file, uint32_t value) {
  if (IsBigEndian()) value = Reverse(value);
  file.write(reinterpret_cast<char*>(&value), sizeof(value));
}

我如何不能每次需要获取Little Endian值时都计算它,而是在编译时计算它并使用宏在Little Endian机器上写入纯数据并在Big Endian机器上反转?

c++ compilation macros endianness
1个回答
0
投票

你需要明白,编译机和运行机是不同的机器。

为了能够编译此函数以消除运行时的字节顺序依赖性,您可以使用包含您正在编译的体系结构的构建配置文件。这些配置文件及其工作方式将根据您的 IDE 和编译器而变化。

设置后,您可以包含预编译指令以在编译时推断字节序。举个小例子:

#if defined(BIGENDIAN_ARCH1) | (BIGENDIAN_ARCH2)
    #define BIGENDIAN
#endif

...

void Write(std::ofstream& file, uint32_t value)
{
#ifdef BIGENDIAN
  uint32_t result;
  uint8_t* pointer_to_result = reinterpret_cast<uint8_t*>(&result);
  uint8_t* pointer_to_value = reinterpret_cast<uint8_t*>(&value);
  pointer_to_result[0] = pointer_to_value[3];
  pointer_to_result[1] = pointer_to_value[2];
  pointer_to_result[2] = pointer_to_value[1];
  pointer_to_result[3] = pointer_to_value[0];
  value = result;
#endif

  file.write(reinterpret_cast<char*>(&value), sizeof(value));
}

在示例中,BIGENDIAN_ARCH1 和 BIGENDIAN_ARCH2 是使用大字节序的架构。这意味着您的代码必须包含您有兴趣编译的所有目标架构。

© www.soinside.com 2019 - 2024. All rights reserved.