[colug-432] c++ struct serialization?

Rick Hornsby richardjhornsby at gmail.com
Fri Dec 13 00:23:32 EST 2019


I can do higher level languages like Python/Ruby “scripts”, but when
it comes to C/C++ it seems like a different world. Probably because
I’ve spent so little time in that world, especially over the last
several years.

This is an Arduino/ESP32 project, but the trouble I’m having is with
my C++. I’ve been trying for a few days to understand what’s happening
in this example -

https://github.com/espressif/arduino-esp32/blob/master/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino

I understand enough of it to know that I'm trying to do something
similar with an ESP32 microcontroller project, where when a command
comes over the network to change a setting (that part is done and
working), that setting is persisted to EEPROM (“preferences”) so that
when power is lost, it will resume what it was doing when it starts
back up. My struct is similar to the example:

typedef struct {
    u8_t mode;
    u16_t activation_threshold;
    u8_t scheme_in_use;
    // u8_t custom_scheme[9]; // 3*RGB, could probably be 3*24bit (32) ints.
} settings_t;

One difference is that ‘activation_threshold’ in mine is a 16 bit int,
whereas the example they’re all 8 bits.

This creates a really, really weird thing I can’t figure out to where
the sizeof() the struct is 1 byte for every 8 bit value, but if
there’s a 16 bit value, there are 2 extra bytes. For example, if we
ignore the 9 byte array ‘custom_scheme’ - we should have a 4 byte
struct. For whatever reason, it’s 6. If I split activation_threshold
into two 8 bit ints, the size of the struct is 4 bytes. Playing around
with the struct, making one 32bit, moving that 32 bit to a different
position in the struct, etc is coming up with different sizes. I
suspect there’s some kind of memory allocation thing happening that I
don’t understand.

Either way. The more pressing but related thing is that I’m struggling
to figure out how to serialize the struct into a byte array (?), and
un-serialize it back from a byte array into a struct. This terrible
looking monstrosity is all I’ve been able to figure out for the
retrieval part:

size_t settingsLen = prefs.getBytesLength("settings");
char buf[settingsLen];
prefs.getBytes("settings", buf, settingsLen);
settings.mode = buf[0];
settings.activation_threshold = (buf[1] << 8) | (buf[2] & 0xff);
settings.scheme_in_use = buf[3];
settings.custom_scheme[0] = buf[4];
// …and so on.


There’s no way the code should be this primitive … or better put,
dumb? But if I try to follow the example more closely, using the cast
like he does on line 29 of the example, the 16 bit value and
everything after it is all screwy. It doesn’t seem to be as simple as
the bytes go back into the slots of memory where they should?

Any ideas?

Thanks!



More information about the colug-432 mailing list