13

How would you convert any struct into byte array on processors with little-endian?

cpx
  • 17,009
  • 20
  • 87
  • 142

6 Answers6

17

You can use a char* to access any type of object in C++, so:

struct S
{
    int a;
    int b;
    // etc.
};

S my_s;

char* my_s_bytes = reinterpret_cast<char*>(&my_s);

// or, if you prefer static_cast:
char* my_s_bytes = static_cast<char*>(static_cast<void*>(&my_s));

(There is at least some debate over the correctness of the reinterpret_cast vs. the static_cast; in practice it doesn't really matter--both should yield the same result)

Community
  • 1
  • 1
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 1
    :-) too many language improvements now on C++. Whereas before, this would suffice: `char* b = (char*)&my_s;` Perhaps if i learn C++ again, I'll read something about those cast constructs first. – Michael Buen Apr 22 '10 at 16:04
  • 4
    @Michael: That C-style cast is the same as the `reinterpret_cast` in this case, because no combination of `static_cast` and `const_cast` is valid. Using the C++ style casts guarantees you get the cast you intend; the C-style cast basically just tries a sequence of five different types of casts until it finds one that works. – James McNellis Apr 22 '10 at 16:06
  • The answer is right given the struct you specified. However, throw some shorts, large_integers, or character data in there and it is horribly wrong. – T.E.D. Apr 22 '10 at 16:29
  • @T.E.D.: "horribly wrong" depends entirely on how the char array is to be used. Certainly there are times where this is not the answer, but frequently this is good enough. The requirements were certainly underspecified. – James McNellis Apr 22 '10 at 17:46
10

I like to use a union:

typedef struct b {
  unsigned int x;
  unsigned int y;
} b_s;

typedef union a {
  b_s my_struct;
  char ary[sizeof(b_s)];
} a_u;
Cameron Tacklind
  • 5,764
  • 1
  • 36
  • 45
WhirlWind
  • 13,974
  • 3
  • 42
  • 42
10
(char*)&someStruct
Andrey
  • 59,039
  • 12
  • 119
  • 163
3

What are you trying to do? If you're trying to serialize the struct so you can save it to a file or pass it in a message, you're better off using a tool designed for that like boost::serialization.

If you just want an array of bytes you could reinterpret_cast<char*> as others have mentioned, or do:

MyStruct s;
char [] buffer = new char[sizeof(s)];
memcpy(&buffer, &s, sizeof(s));
David
  • 7,011
  • 1
  • 42
  • 38
1

I would peer into the void*.

struct gizmo 
{
//w/e
};

//stuff

gizmo *G = new gizmo;

void* bytearray = (void*)G;

How your struct gets packed is ambiguous and depends on compiler, ABI, and CPU. You'll have to figure that out from your manuals & some assembly reading.

Paul Nathan
  • 39,638
  • 28
  • 112
  • 212
  • 1
    You can't access bytes through a void* – nos Apr 22 '10 at 16:10
  • Since you cannot dereference a void*, you can't access whatever it points to(perhaps bar using memcpy, in which case a intermediate void* isn't needed) foo[0]; is a compiler error if foo is a void*. Use an unsigned char* to access individual bytes. – nos Apr 22 '10 at 21:05
0

The problem with all of these answers is that you can't really do dumb byte swapping without knowing something about the data you are swapping. Character data does not get swapped. 64-bit integers need a different kind of swapping depending on exactly how the two processors in question implemented them.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134