C/C++ - Caster une structure vers un tableau de bytes (et opération inverse)
Posted on ven. 27 décembre 2024 in Programming
Sur un projet utilisant la mémoire 47C16, mais où mon microcontrôleur (STM32L412) me retourne des uint16_t
et uint32_t
, je dois malgré tout réaliser une conversion vers un buffer de uint8_t
pour permettre leur transmission correcte via I2C.
La méthode ci-dessous (code et exécution possible sur OnlineGDB) est inspirée de plusieurs posts Stackexchange (dont celui-ci). Elle utilise un casting entre pointeurs pour déconstruire puis reconstruire la structure.
#include <stdio.h>
#include <stdint.h>
typedef struct {
uint32_t potentio;
uint16_t temperature;
} capt;
int main()
{
capt c = {0xFF, 0xAAAA};
uint8_t *captptr;
capt* reconstructed_capteur;
captptr = (uint8_t*)&c;
reconstructed_capteur = (capt*) captptr;
int structsize = sizeof(capt);
printf("Structure size = %d\n", structsize);
printf("Decomposition capteur\n");
for(int i=0; i<(structsize/1); ++i) {
printf("Block %d = %d\n", i, captptr[i]);
}
printf("Recomposition capteur\n");
printf("Potentio = %d, temperature = %d", reconstructed_capteur->potentio, reconstructed_capteur->temperature);
return 0;
}
Il semble y avoir d’autres façons de procéder.
D’après cet autre post Stackexchange, il est possible d’utiliser un static_cast
ou un reinterpret_cast
en C++.
Une autre méthode utilise la fonction memcpy
(C). Un test sur OnlineGDB semble fonctionner.
#include <stdio.h>
#include <stdint.h>
typedef struct {
uint32_t potentio;
uint16_t temperature;
} capt;
int main()
{
capt c = {0x7FFFFFFF, 0b1010101010101010};
printf("Decomposing the structure\n");
uint8_t receiving[sizeof(c)];
memcpy(receiving, &c, sizeof(c));
for(int i=0; i<sizeof(c); ++i) {
printf("Byte %d = %b\n", i, receiving[i]);
}
printf("Recomposing the structure\n");
capt cbis;
memcpy(&cbis, receiving, sizeof(cbis));
printf("cbis.potentio = %:032b (%i)\n", cbis.potentio, cbis.potentio);
printf("cbis.temperature = %b (%d)\n", cbis.temperature, cbis.temperature);
return 0;
}
Sur le forum Microchip, un exemple est donné pour décomposer un flottant en une série de bytes pour un envoi direct via liaison USART, mais il n’est pas fait mention de la reconstruction éventuelle de l’autre côté…
En bref, il y a plusieurs manières de procéder. Il faudrait que je me plonge un peu plus là-dedans pour voir quels sont les avantages/inconvénients, mais la méthode donnée au début de cet article fonctionne bien dans mon cas d’application, donc pour le moment je vais m’y tenir.