3

C 程序如何在 RUN 时(不是编译时)确定它是在 Little-Endian 还是 Big-Endian CPU 上运行?

它必须是“运行时”检查而不是“编译时”的原因是因为我正在使用带有 Intel-CPU 的 MAC 以 MAC OSX 的通用二进制格式构建程序。该程序预计可在 Intel 和 Power-PC CPU 上运行。即,通过MAC上的通用二进制格式,我想使用Intel-CPU构建一个程序并在PPC CPU下运行它。

我的程序中需要 CPU 检查的逻辑是 64 位整数的主机到网络字节顺序更改函数。现在我让它盲目地交换字节顺序,这在 Intel-CPU 上工作正常,但在 PPC 上中断。这是C函数:

unsigned long long
hton64b (const unsigned long long h64bits) {
   // Low-order 32 bits in front, followed by high-order 32 bits.
   return (
       (
        (unsigned long long)
        ( htonl((unsigned long) (h64bits & 0xFFFFFFFF)) )
       ) << 32
      )
      |
      (
       htonl((unsigned long) (((h64bits) >> 32) & 0xFFFFFFFF))
      );
}; // hton64b()

以跨平台方式执行此操作的任何更好方法?

谢谢

4

4 回答 4

2

不要费心检查;只需在需要独立于网络的值的地方使用 hton* 即可。有了一个好的设计,它应该仅限于在你的程序和任何需要网络独立整数之间接口的模块。

在已经按网络顺序排列的大端系统上,hton* 可能只是一个宏,所以它是免费的。在小端系统上,无论如何您都需要这样做,因此检查是否需要这样做只会减慢您的速度。

如果这还不够,那么您需要更好地解释您要完成的工作以及为什么需要在运行时了解系统的字节序。

于 2009-12-02T17:29:52.990 回答
1
  • 将有预处理器宏可用于测试它是大端还是小端。例如
   #ifdef LITTLE_ENDIAN
   做小端方式
   #别的
   做大端的方式
   #万一。

这是编译时间,但胖二进制文件的源代码会为每个架构单独编译,这不是问题。

  • 我不确定macosx 在 sys/endian.h 中是否有 betoh64() 函数——如果有——使用它会做正确的事情。
  • 最后一种方法是简单地以对主机端不敏感的方式对单个字节进行解包 - 您只需要知道字节在源中的顺序。

    uint64_t unpack64(uint8_t *src)
    {
       uint64_t val;
    
       val  = (uint64_t)src[0] << 56;
       val |= (uint64_t)src[1] << 48;
       val |= (uint64_t)src[2] << 40;
       val |= (uint64_t)src[3] << 32;
       val |= (uint64_t)src[4] << 24;
       val |= (uint64_t)src[5] << 16;
       val |= (uint64_t)src[6] <<  8;
       val |= (uint64_t)src[7]      ;
    
       return val;
    }
    
于 2009-12-02T18:54:04.693 回答
0

您是否意识到 Mac 上的通用二进制文件被编译多次,每个架构一次编译?我想当您谈论编译时间时,您指的是使用您的配置/制作系统来通知源......只需使用 gcc 常量(如 LITTLE_ENDIAN )

于 2009-12-02T17:19:52.260 回答
0

您无需在运行时检查字节顺序。当您将应用程序编译为通用二进制文件时,它会使用适当的定义和宏进行多次编译,即使您是在 Intel 机器上构建的。在运行时,mach-o 加载程序将从您的通用二进制文件(即 PowerPC 上的 ppc 或 Intel 上的 i386)中选择最佳架构来运行。

通用二进制并不意味着一个二进制用于多种架构。这意味着一个胖二进制文件包含一个用于一种架构的二进制文件。

请参阅http://developer.apple.com/legacy/mac/library/documentation/MacOSX/Conceptual/universal_binary/universal_binary_intro/universal_binary_intro.html了解更多详情。

于 2009-12-03T10:30:42.397 回答