我正在解析一种以大端方式表示数字的文件格式。
通常我会包含 aarp/inet.h 并使用 ntohl()。
在我使用的各种嵌入式c环境中inet.h不存在
有没有我可以使用的 ntohl() 的标准等价物,这样我就不需要引入 inet.h?
最佳答案
已更新
现在确定您为什么不想在 ntohl 中链接,但这应该可以工作,尽管比您的平台提供的慢一点。
代码经过优化以使用编译时检查来检测 Intel 处理器(始终为 Little Endian)。如果您知道它是字节顺序,您可以修改 #if defined...
block 以包含您自己的处理器。否则,它会回退到执行检测 Little Endian 的简单运行时检查。
#include <stdint.h> // if stdint.h is not available, then "typedef int int32_t" and "typedef unsigned int uint32_t" as appropriate
int compile_time_assert[(sizeof(int32_t) == 4)?1:-1];
int32_t NTOHL(int32_t value)
{
#if defined(_M_X64) || defined(_M_IX86) || defined(_M_X64) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__amd64__)
const int isBigEndian = 0;
#elif defined(sparc)
const int isBigEndian = 1;
#else
const int32_t test = 0x01020304;
const char* ptr = (const char*)&test;
int isBigEndian = (ptr[0] == 0x01);
#endif
int32_t result = value;
if (!isBigEndian)
{
uint32_t uvalue = (uint32_t)value; // cast to unsigned for shifting safely
result = (uvalue >> 24) | ((uvalue >> 8) & 0x0000FF00) | ((uvalue << 8) & 0x00FF0000) | (uvalue << 24);
}
return result;
}
所有这些都假设只有两种可能的字节顺序架构(大和小)。如今,这应该是所有内容的 99.9%。如果你想让它在一个非常过时的架构上工作——那些留着灰 mustache 的老家伙会谈论 6 位字节、EBCIDIC 和 1 的补码,你将需要适本地修改上面的代码。
关于c - 无需 inet.h 可移植地读取大端数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33492352/