如何在 C++ 中的大端和小端值之间进行转换? [复制]
Posted
技术标签:
【中文标题】如何在 C++ 中的大端和小端值之间进行转换? [复制]【英文标题】:How do I convert between big-endian and little-endian values in C++? [duplicate] 【发布时间】:2009-03-15 17:21:41 【问题描述】:如何在 C++ 中的大端和小端值之间进行转换? 我正在使用 VC++ 6.0。当我使用 _byteswap_ulong() 函数时,它需要头文件 intrin.h。 当我包含头文件时,它会报告一个错误,指出编译器不兼容,并且 intrin.h 用于 gcc 编译器。 那么除了这个函数之外,VC++中还有没有其他函数可以实现big-endian和little-endian值之间的转换?
【问题讨论】:
如果您要求在 VC++ 中执行此操作,为什么 gcc 的错误很重要?反正_byteswap_ulong不是标准函数。 【参考方案1】:在符合 POSIX 的系统中,您拥有标准的 byteswap(3) 函数:
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
这些专供网络使用,如名称所示(主机到网络长、主机到网络短等)
GNU 和 BSD 系统也提供 endian(3) 函数:
#define _BSD_SOURCE
#include <endian.h>
uint16_t htobe16(uint16_t host_16bits);
uint16_t htole16(uint16_t host_16bits);
uint16_t be16toh(uint16_t big_endian_16bits);
uint16_t le16toh(uint16_t little_endian_16bits);
uint32_t htobe32(uint32_t host_32bits);
uint32_t htole32(uint32_t host_32bits);
uint32_t be32toh(uint32_t big_endian_32bits);
uint32_t le32toh(uint32_t little_endian_32bits);
uint64_t htobe64(uint64_t host_64bits);
uint64_t htole64(uint64_t host_64bits);
uint64_t be64toh(uint64_t big_endian_64bits);
uint64_t le64toh(uint64_t little_endian_64bits);
(在 OpenBSD 上,位宽的数字总是在函数的末尾:例如 be64toh() 与 betoh64()。)
否则,大多数人都会定义自己的宏或函数:
#define bswap16(x) ((x)>>8 | ((x)&255)<<8)
#deinfe bswap32(x) ((bswap16((x)>>16)&65535)|(bswap16((x)&65535)<<16))
/* etc. */
您还可以使用汇编内在函数,例如 x86 上的 bswap 指令。 __builtin_bswap64
在 GCC 和 ICC 中。从 VS7.0 开始,VS 中也有类似的东西。
【讨论】:
+1,但我认为您不需要使用内在函数,因为它们会在您使用库函数时自动使用。 我不依赖它。我意识到一些工具链足够聪明,可以做到这一点,但我仍然从未见过编译器将 fsqrt() 调用转换为 3 指令 SSE 等效项。 greyfade:视情况而定。 VC++ 可以选择为内置函数使用内在函数。当然,您需要针对支持 SSE 的平台。 GCC 也有类似的选项。但是当然,如果你不向编译器指定 SSE 可用,它就不会被使用。 哦,我知道。但即使是带有适当 -march 开关的 GCC 有时也不会以这种方式优化它。 (或者,更确切地说,至少在 GCC 4 之前没有。我最近没有做太多的实验。我根本不依赖它。)【参考方案2】:Docs 似乎说这些函数存在于 stdlib.h 中。
【讨论】:
任何以下划线开头的都是非标准定义。 我不认为他要求的是标准方法,他要求的是 VC++ 中的方法,除非我大错特错?以上是关于如何在 C++ 中的大端和小端值之间进行转换? [复制]的主要内容,如果未能解决你的问题,请参考以下文章