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