7

I have a struct:

//Custom packet structure.
struct UserPacket
{
 __int64 pingTime;
} CustomPacket;

I have already figured out how to convert it to a char*. Now I want to convert the char* back to the struct. Any suggestions?

InfinateOne
  • 81
  • 1
  • 1
  • 3
  • 1
    How you convert it back depends entirely on how you did the forward conversion. Please post details of the forward conversion. – CB Bailey Apr 11 '10 at 11:35
  • Looks like you're trying to serialise the data. Be very careful of padding and alignment issues here (although your single member example should be ok). Are you writing the char* to a file or some other stream that leaves the process? There may be other issues such as endian-ness to consider. – philsquared Apr 11 '10 at 12:25
  • Beware of endianness if this data is going between different computers (which it looks like). – Potatoswatter Apr 11 '10 at 13:06

2 Answers2

12

If it's C++:

char* theCharPtr; // has your converted data

UserPacket* fromChar = reinterpret_cast<UserPacket*>(theCharPtr);
Zoli
  • 1,137
  • 7
  • 12
  • 5
    Since this thread's a prominent search result, it should be noted that converting from `[[un]signed] char *` to `SomethingElse *` is not officially valid by the Standard. Strict aliasing rules only allow `SomethingElse *` to `char *`. Sure, most implementations _do_ allow this & do what most folk expect - & fwiw, I exploit this sometimes - but it should always be prominently warned it's not guaranteed behaviour. In particular it's conceivable that on some implementations, a resulting `SomethingElse` contains a fundamental-type member that is now misaligned, making the program crash at runtime – underscore_d Jan 06 '16 at 12:16
  • @underscore_d Does this also apply to the C standard? i.e casting from `char*` to `SomethingElse*`? – Nubcake May 03 '20 at 22:43
  • @Nubcake Yes. However, in C, you can use a `union` to get around that, but in C++ you cannot. See: [Casting a char array to be of type struct *](https://stackoverflow.com/a/48100169/2757035) Saying that, from C++20ish onwards (papers are in flight), it will finally become allowed to 'create' a suitably data-only object from raw bytes of memory by `reinterpret_cast`. Currently we have to use `memcpy()` or such to get around the Standardese as it's presently written. – underscore_d May 05 '20 at 07:25
  • 1
    @underscore_d I was under the impression that char, unsigned char, and std::byte types were explicitly allowed, but not signed char. – Lambo Oct 22 '21 at 01:47
  • 1
    @Lambo Right! [C11 says](https://stackoverflow.com/a/40575162/2757035) `signed char` is OK. But [cppref](https://en.cppreference.com/w/cpp/language/reinterpret_cast) only says `unsigned char`, unqualified `char`, & `std::byte`. [The Standard](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4868.pdf) qualifies many allowances as for `unsigned char` or unqualified `char` only, incl 7.11.11: "attempts to access the stored value of an object through a glvalue whose type is not similar to one of the following types [mean] the behavior is undefined". *Others* only allow `unsigned char` & `byte` – underscore_d Oct 23 '21 at 13:51
5

Typecast it. Here are some examples (two using type casting).

CustomPacket  customPacket;

char *          p = (char *) &customPacket;

CustomPacket *  pPacket    = (CustomPacket *) p;
CustomPacket *  pAlternate = &customPacket;

Hope this helps.

Sparky
  • 13,505
  • 4
  • 26
  • 27
  • 2
    You should avoid c-style cast in C++, as the compiler will try each and every one cast until it finds the one that "is ok". Use it like @Zoltan, as then you can clearly see what the author is doing and what he had on his mind. – jaor Jul 30 '14 at 05:36
  • @jaor - Fascinating! I did not know this before about C++. I'm learning something new every day. :) – Sparky Jul 30 '14 at 20:19