1

我正在玩包含以下代码的开源

uint32_t addr = htonl(* (uint32_t *)RTA_DATA(rth));
if (htonl(13) == 13) {
    // running on big endian system
} else {
    // running on little endian system
    addr = __builtin_bswap32(addr);
}

看起来它检查系统是大端还是小端if (htonl(13) == 13)。这是正确的吗?你能解释一下为什么要这样检查吗?为什么他使用 13?

addr = __builtin_bswap32(addr);导致编译问题“未定义的引用”。有解决方案吗?看起来该功能在新版本的 gcc 库中不再存在。这是正确的吗?

编辑:

我使用的工具链是 toolchain-i386_gcc-4.1.2_uClibc-0.9.30.1

对于我在编译中使用的选项:

  • 对于 c to object 编译选项:

    -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -I. -I/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/usr/include -O2 -pipe -march=i486 -funit-at-a-time -fhonour-copts -D_GNU_SOURCE -MT

  • 对于二进制对象(链接器)

    -O2 -pipe -march=i486 -funit-at-a-time -fhonour-copts -D_GNU_SOURCE -L/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/usr/lib -L/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/lib -L/opt/lampp/htdocs/backfire/staging_dir/toolchain-i386_gcc-4.1.2_uClibc-0.9.30.1/lib -Wl,-rpath-link=/opt/lampp/htdocs/backfire/staging_dir/target-i386_uClibc-0.9.30.1/usr/lib

4

1 回答 1

2

htonl将“主机顺序”数字转换为网络字节顺序。主机顺序是您在运行代码的系统上拥有的任何字节顺序。网络字节顺序是大端。如果主机到网络是大到大,这意味着没有变化——这就是13->13将验证的。另一方面,如果主机到网络是从小到大,这意味着您将进行交换,因此最不重要的字节13(最不重要的是因为将其更改为 1 只会将总数更改为 1)将成为大多数-significant-byte 13(主要是因为将该字节更改为一个最大的数量)和13-> (13 << 24)

13具体不重要。你可以使用任何数字,只要它的小端表示与大端表示不同。(0会很糟糕,因为0字节交换仍然是0. 也一样(65536 + 256),因为 32 位表示00 01 01 00同时采用大端和小端。

请注意,还有混合端系统,对于 32 位数字0x12345678,您的字节顺序不是12 34 56 78(big-endian) 或78 56 34 12(little-endian):34 12 78 56我相信其中之一。这些系统并不常见,但它们仍然存在,并且这里的代码无法正确处理它们。

http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Other-Builtins.html and http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Other-Builtins.html suggest __builtin_bswap32 was added in gcc 4.3, so your gcc 4.1.2 toolchain wouldn't have it.

于 2013-02-22T22:29:25.703 回答