ОБЗОР
#define _BSD_SOURCE /* См. feature_test_macros(7) */
#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);
ОПИСАНИЕ
Эти функции преобразуют кодирование байт целых значений из/в порядок байт,
используемом в работающем ЦП («порядок байт узла»), от младшего к старшему
(little-endian) и от старшего к младшему (big-endian).
Число nn в имени каждой функции показывает размер целого, с которым работает функция — может быть 16, 32 или 64 бита.
Функции с именами вида «htobenn» преобразуют число с порядком байт узла в число с порядком байт от старшего к младшему.
Функции с именами вида «htolenn» преобразуют число с порядком байт узла в число с порядком байт от младшего к старшему.
Функции с именами вида «benntoh» преобразуют число с порядком байт от старшего к младшему в число с порядком байт узла.
Функции с именами вида «lenntoh» преобразуют число с порядком байт от младшего к старшему в число с порядком байт узла.
ВЕРСИИ
Эти функции добавлены в glibc версии 2.9.
СООТВЕТСТВИЕ СТАНДАРТАМ
Это нестандартные функции. Подобные функции есть в BSD, где вместо
<endian.h> для них требуется заголовочный файл
<sys/endian.h>. К сожалению, NetBSD, FreeBSD и glibc не следуют
изначальному соглашению об именах функций в OpenBSD, где часть nn всегда
находится в конце имени функции (то есть, например, в NetBSD, FreeBSD и
glibc используется «be32toh» вместо эквивалентной «betoh32» из OpenBSD).
ЗАМЕЧАНИЯ
Данные функции похожи на функции старого семейства
byteorder(3). Например, be32toh() идентична ntohl().
Преимущество функций byteorder(3) в том, что они являются стандартными и доступны во всех системах UNIX. С другой стороны, тот факт, что они разрабатывались для использования в контексте TCP/IP означает, что среди них нет функций для 64-битных значений и чисел с порядком байт от младшего к старшему, описанных в этой странице.
ПРИМЕР
Ниже представлена программа, которая выводит результаты преобразования
целого с порядком байт узла в целое с порядком байт от младшего к старшему и
от старшего к младшему. Так как порядок байт узла будет эквивалентен порядку
от младшего к старшему или от старшего к младшему, то реально выполняется
только одно преобразование. Если эта программа запускается на системе с
порядком байт от младшего к старшему, например x86-32, то мы увидим
следующее:
$ ./a.out x.u32 = 0x44332211 htole32(x.u32) = 0x44332211 htobe32(x.u32) = 0x11223344
Исходный код программы
#include <endian.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { union { uint32_t u32; uint8_t arr[4]; } x; x.arr[0] = 0x11; /* низший адресуемый байт */ x.arr[1] = 0x22; x.arr[2] = 0x33; x.arr[3] = 0x44; /* высший адресуемый байт */ printf("x.u32 = 0x%x\n", x.u32); printf("htole32(x.u32) = 0x%x\n", htole32(x.u32)); printf("htobe32(x.u32) = 0x%x\n", htobe32(x.u32)); exit(EXIT_SUCCESS); }