0

I have struct with the following elements. Plus the structure is complety padded.

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

This structure is a little endian. I mean when I print this structure on my big endian machine I get the following

if c=1 , d=2, e[0] =3, e[1]=4. I get

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

a and b are swapped. further, e[1] is swapped with c and e[0] is swapped with d.

I am using htonl function like the following. but, it is not working, can anyone suggest me a good answer.

Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
Invictus
  • 2,653
  • 8
  • 31
  • 50
  • How do you print it, and what is "like the following"? The order in which `struct` members are placed in memory is prescribed by the standard, don't expect any compiler to violate that just because of endianness. – Daniel Fischer Nov 30 '12 at 00:55
  • I don't see how endenianess could cause elements to be swapped. Something else is wrong. Show your code. – Carey Gregory Nov 30 '12 at 00:57
  • That isn't an endian issue. An endian issue happens when `uint16_t` on a LE machine with a value of `1` becomes `256` (or 0x0100 if you prefer) on a BE machine. What you're seeing is data that is not matching up with what you "sent". Endian difference does not swap structure elements (unless you're doing something foolish like calling `*((uint32_t*)&s) = htonl(*(uint32_t*)&s)`, where `s` is a structure like you have above. Then all bets are off). – WhozCraig Nov 30 '12 at 01:08

2 Answers2

3

Endian-ness only applies to individual fields, not the order of struct fields. Of the fields you list, only the multi-byte integer fields defined as uint16_t will are governed by endian-ness the uint8_t are single byte, so there is no ordering issue to consider. The array of single byte values will also maintain the same length regardless of the endian-ness.

To convert the uint16_t, you will want to use the htons() function instead of htonl(). The htonl() function expects a long which will typically be at least 4 bytes.

uint16_t netShort = htons(uint16_t hostShort);

Or for your example struct:

struct.a = htons(struct.a);
struct.b = htons(struct.b); 
Ben Kelly
  • 1,304
  • 7
  • 9
0

For the first two elements a and b, they are uint16_t, so you should use htons/ntohs to convert them. The rest three elements c, d and e, they are uint8_t, you don't need to convert them.

By the way, I don't know if or not you use ntohl on the variable ad (struct), just clarify to you that you should convert each element of a struct one by one rather than convert the entire struct variable with ntohl/ntohs/htonl/htons.

TieDad
  • 9,143
  • 5
  • 32
  • 58