I'm wondering if this is possible with C++/Arduino and/or how the best way to address this.
My sketch needs to process information coming via RS485 data packets. The first byte of the packet identifies the packet type and thus the data structure that follows. All packets are the same length. To simplify, assume there are 3 packet structures:
struct CmdStruct {
byte packettype; // 1 for command packet
byte msgno;
byte stat;
byte command;
unsigned long datetime;
} PacketA ;
struct DataStruct {
byte packettype; // 2 for data packet
byte msgno;
int alpha;
int beta;
int delta;
} PacketB ;
struct ReadStruct {
byte msgread[8]; // This is actually used when reading from the RS485 data
} PacketR;
Is it possible to overlay the 3 structures so that they are referencing the same 8 bytes of memory? And if so, what's this called?
Note that in practice, the data structures are much longer.
If C++ doesn't support this, is there a way to copy PacketR to PacketA or PacketB?
Yes, that is very normal. I forget how it is done in C++ but we used pointer based structures. The key is to have a standard start. The first byte must be length in order to get to the next msg, the second byte must be message type so you know what structure you are working with.
My system did this a few million times a day for years before we were bought out and it never failed to understand and process the data.
To be aware that these structures has the same size on 8bit Arduino only. If you try to send it to, say, ESP32 - these structures becames the different
I dont think a union is the best way to go. I think it would be a lot "cleaner" to define the basic contents of one of the structures as a base class, then define a numer of derived classes for each specific type of structure. That way you can use a pointer or reference to the base class to reference any derived class for bookkeeping, with a pointer or reference to the specific class for using/updating the unique structures.
this kinda thing is common in communication. Ethernet frames are captured, ID'd by looking at some header bytes and the content copied to a struct that defines the sub-fields with the packet. Similar for IP frames carried within an Ethernet frame and themselves carrying TCP.
Never having tried this, I'm surprised to hear that.
However, a struct in C++ is the same thing as a class without a constructor, so an alternate way would be a base class and subclasses. I would use have a base class pointer to the data, then dereference the pointer by casting to the desired subclass.
It's a clean method and won't have any surprises. I'm not a big fan of unions.
It's risky at best. Casting from a base class to a subclass (downcasting) requires dynamic_cast. This is not supported on many small processors as it consumes code space and incurs a runtime penalty.