Как я могу преобразовать прямой порядок байтов в прямой, используя htonl

У меня есть структура со следующими элементами. Кроме того, конструкция полностью заполнена.

typedef struct {
    uint16_t a;
    uint16_t b;
    uint8_t c;
    uint8_t d;
    uint8_t e[6];
} ad;

Эта структура имеет порядок следования байтов. Я имею в виду, что когда я печатаю эту структуру на своей машине с прямым порядком байтов, я получаю следующее

если c=1 , d=2, e[0] =3, e[1]=4. я получил

c=4, d=3, e[0] = 2 и e[1]=1.

а и б меняются местами. далее e[1] заменяется на c, а e[0] заменяется на d.

Я использую функцию htonl, как показано ниже. но это не работает, может ли кто-нибудь предложить мне хороший ответ.


person Invictus    schedule 30.11.2012    source источник
comment
Как вы его печатаете и что из себя представляет следующее? Порядок, в котором элементы struct размещаются в памяти, предписан стандартом, не ожидайте, что какой-либо компилятор нарушит его только из-за порядка следования байтов.   -  person Daniel Fischer    schedule 30.11.2012
comment
Я не понимаю, как endenianess может привести к замене элементов. Что-то еще не так. Покажи свой код.   -  person Carey Gregory    schedule 30.11.2012
comment
Это не проблема с порядком байтов. Проблема с порядком байтов возникает, когда uint16_t на машине LE со значением 1 становится 256 (или 0x0100, если хотите) на машине BE. То, что вы видите, это данные, которые не совпадают с тем, что вы отправили. Разница в порядке байтов не меняет местами элементы структуры (если вы не делаете что-то глупое, например, вызываете *((uint32_t*)&s) = htonl(*(uint32_t*)&s), где s — это структура, как у вас выше. Тогда все ставки отключены).   -  person WhozCraig    schedule 30.11.2012


Ответы (2)


Endian-ness применяется только к отдельным полям, а не к порядку полей структуры. Из полей, которые вы перечисляете, только многобайтовые целые поля, определенные как uint16_t, будут регулироваться порядком байтов, а uint8_t являются однобайтовыми, поэтому нет необходимости рассматривать проблему порядка. Массив однобайтовых значений также будет поддерживать одинаковую длину независимо от порядка следования байтов.

Чтобы преобразовать uint16_t, вы захотите использовать функцию htons() вместо htonl(). Функция htonl() ожидает длинное значение, которое обычно составляет не менее 4 байтов.

uint16_t netShort = htons(uint16_t hostShort);

Или для вашего примера структуры:

struct.a = htons(struct.a);
struct.b = htons(struct.b); 
person Ben Kelly    schedule 30.11.2012

Для первых двух элементов a и b они равны uint16_t, поэтому для их преобразования следует использовать htons/ntohs. Остальные три элемента c, d и e — это uint8_t, их конвертировать не нужно.

Кстати, я не знаю, используете ли вы ntohl для переменной ad (struct), просто поясню вам, что вы должны преобразовывать каждый элемент структуры один за другим, а не преобразовывать всю переменную структуры с помощью ntohl/ntohs. /хтонл/хтонс.

person TieDad    schedule 30.11.2012