我应该#include使用'htonl'?

时间:2010-07-04 03:36:54

标签: c include endianness

我想在我的ruby c扩展中使用htonl函数,但不想使用随附的任何其他互联网内容。什么是#include最简约的文件仍然可移植?浏览计算机上的标题文件,我可以看到machine/endian.hsys/_endian.h让我使用它们,但我不确定这是不是一个好主意。

3 个答案:

答案 0 :(得分:13)

standard标题是:

#include <arpa/inet.h>

您不必担心该标头中定义的其他内容。它不会影响您编译的代码,并且只会对编译时间产生轻微影响。

编辑:您可以测试一下。创建两个文件,htonl_manual.c

// non-portable, minimalistic header
#include <byteswap.h>
#include <stdio.h>
int main()
{
    int x = 1;
    x = __bswap_32(x);
    printf("%d\n", x);
}

和htonl_include.c:

// portable
#include <arpa/inet.h>
#include <stdio.h>
int main()
{
    int x = 1;
    x = htonl(x);
    printf("%d\n", x);
}

将它们组装在-O1,然后采取差异:

gcc htonl_manual.c -o htonl_manual.s -S -O1
gcc htonl_include.c -o htonl_include.s -S -O1
diff htonl_include.s htonl_manual.s

对我来说,唯一的区别是文件名。

答案 1 :(得分:2)

在Windows上,arpa/inet.h不存在,因此this answer将不存在。包括:

#include <winsock.h>

所以include块的便携式版本(总是最好提供一个):

#ifdef _WIN32
#include <winsock.h>
#else
#include <arpa/inet.h>
#endif

答案 2 :(得分:-1)

如果您不想包含与网络相关的任何内容,那么自己声明htonl是完全有效的。只需#include <stdint.h>即可获得uint32_t并使用以下原型:

uint32_t htonl(uint32_t);

参考:POSIX:http://www.opengroup.org/onlinepubs/9699919799/functions/htonl.html

您也可以通过使用联合测试字节顺序(在编译时)来实现自己的。这不需要任何奇怪的ENDIAN宏或#ifdefs。