Reputation: 11
If we have a POD struct say A, and I do this:
char* ptr = reinterpret_cast<char*>(A);
char buf[20];
for (int i =0;i<20; ++i)
buf[i] = ptr[i];
network_send(buf,..);
If the recieving end remote box, is not necessarily same hardware or OS, can I safely do this to 'unserialize':
void onRecieve(..char* buf,..) {
A* result = reinterpret_cast<A*>(buf); // given same bytes in same order from the sending end
Will the 'result' always be valid? The C++ standard states with POD structures, the result of reinterpret_cast should point to the first member, but does it mean the actual byte order will be correct also, even if the recieving end is a different platform?
Upvotes: 1
Views: 2322
Reputation: 1049
You may consider using a templatefor this and letting the compiler handle it for you
template<typename T>
struct base_type {
union {
T scalar;
char bytes[sizeof(T)];
};
void serialize(T val, byte* dest) {
scalar = val;
if is_big_endian { /* swap bytes and write */ }
else { /* just write */ }
}
};
Upvotes: 0
Reputation: 477444
No, you cannot. You can only ever cast "down" to char*
, never back to an object pointer:
Source Destination
\ /
\ /
V V
read as char* ---> write as if to char*
In code:
Foo Source;
Foo Destination;
char buf[sizeof(Foo)];
// Serialize:
char const * ps = reinterpret_cast<char const *>(&Source);
std::copy(ps, ps + sizeof(Foo), buf);
// Deserialize:
char * pd = reinterpret_cast<char *>(&Destination);
std::copy(buf, buf + sizeof(Foo), pd);
In a nutshell: If you want an object, you have to have an object. You cannot just pretend a random memory location is an object if it really isn't (i.e. if it isn't the address of an actual object of the desired type).
Upvotes: 3