Что я должен # включить в использование 'htonl'?

Я хочу использовать функцию htonl в моем расширении ruby ​​c, но не хочу использовать какой-либо другой материал, который поставляется с ним. Что будет самым минималистичным файлом для #include, который все еще переносится? Просматривая файлы заголовков на моем компьютере, я вижу, что либо machine/endian.h, либо sys/_endian.h позволят мне использовать их, хотя я не уверен, что это хорошая идея.

Ответ 1

стандартный заголовок:

#include <arpa/inet.h>

Вам не нужно беспокоиться о других материалах, определенных в этом заголовке. Это не повлияет на ваш скомпилированный код и будет иметь лишь незначительный эффект на время компиляции.

EDIT: вы можете проверить это. Создайте два файла, 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

Для меня единственная разница - это имя файла.

Ответ 2

В Windows arpa/inet.h не существует, поэтому этот ответ не подходит. Включение:

#include <winsock.h>

Итак, переносимая версия блока include (всегда лучше предоставить один):

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

Ответ 3

Если вы не хотите включать что-либо связанное с сетью, оно совершенно справедливо для объявления htonl самостоятельно. Просто #include <stdint.h>, чтобы получить uint32_t и использовать следующий прототип:

uint32_t htonl(uint32_t);

Ссылка: POSIX: http://www.opengroup.org/onlinepubs/9699919799/functions/htonl.html

Вы также можете просто реализовать свои собственные, выполнив порядок байтов (в compiletime) с помощью союзов. Это не требует каких-либо нечетных макросов ENDIAN или #ifdefs.