L'initialisation d'un const array dans une struct en C++
Je dois travailler sur un prop. format de fichier binaire et souhaitez le réaliser avec l'utilisation de structures.
J'ai besoin constant séquence d'octets dans mes structures et atm je ne comprends pas comment réaliser cela.
J'ai pensé à quelque chose comme ça:
#include <cstdint>
#pragma pack(push,1)
typedef struct PAYLOAD_INFO {
const uint8_t magicnumber[4] = { 0xFA, 0x11 , 0x28 , 0x33 };
uint16_t UMID;
const uint16_t VID = 1487 ;
uint32_t crc;
};
#pragma pack(pop)
int main (){
PAYLOAD_INFO pldInst;
pldInst.UMID = 5;
pldInst.crc = 0x34235a54;
...
writeToFile(&PAYLOAD_INFO,sizeof(PAYLOAD_INFO));
}
À la fin "pldInst" doit regarder comme ça ( dans la mémoire) , sans tenir compte de la byteorder dans cet exemple:
0x00000000: 0xFA, 0x11 , 0x28 , 0x33
0x00000004: 0x00, 0x05 , 0x05 , 0xCF
0x00000008: 0x34, 0x23 , 0x5a , 0x54
J'ai déjà essayé le "par défaut":
#include <cstdint>
#pragma pack(push,1)
typedef struct PAYLOAD_INFO {
static const uint8_t magicnumber[4];
uint16_t UMID;
static const uint16_t VID = 1487 ;
uint32_t crc;
};
const uint8_t magicnumber[4] = { 0xFA, 0x11 , 0x28 , 0x33 };
#pragma pack(pop)
mais n'a pas l'intention.
Est-il un moyen de le faire sans calculer la taille de la mémoire de chaque structure membre,de l'attribution de nouveaux de la mémoire et de la copie de chaque membre ?
J'utilise g++ 4.6.3.
Égard,
Thomas
Mise à JOUR:
Le c++11 fournies par la solution de @bikeshedder fonctionne très bien mais il compile uniquement avec g++ 4.7 ou plus.
Je pense que vous avez besoin
const uint8_t PAYLOAD_INFO::magicnumber[4] = ...
. Pas à 100%.Bien d'accord alors! 😛
OriginalL'auteur Thomas T. | 2013-02-02
Vous devez vous connecter pour publier un commentaire.
Je déconseille tout type de coulée de
structs
à de la mémoire brute, sauf si vous utilisez une interface de noyau qui est garanti pour fonctionner sur la même machine, il est censé être utilisé de cette façon.Ce n'est pas portable (endian), chaque compilateur ne un peu différente, et la performance est vraiment pas tellement mieux. Dans l'ensemble, il ne justifie pas cette mauvaise pratique.
La raison pour laquelle votre exemple de code ne fonctionne pas sont les membres statiques. Depuis les membres statiques ne font pas partie de l'objet (la classe) seulement
UMID
etcrc
sont écrits de cette façon.Ce code fonctionne uniquement en C++11, mais puisque vous inclure
cstdint
je vais supposer que vous utilisez déjà que la version C++. Si vous n'utilisez pas le C++11, vous devez initialiser les membres dans le constructeur et vous ne devez pas utiliserconst
pour le nombre magique car il ne peut pas être initialisé. (Voir: initialiser un const tableau dans une classe d'initialiseur en C++)Pour C++98, vous devez faire:
OriginalL'auteur bikeshedder
Votre statique est simplement la définition d'un mondial statique. Vous avez besoin d'ajouter une classe rédacteur de devis pour définir la statique de faire partie de votre classe.
Cela dit, comme @bikeshedder mentionne ci-dessous, les statistiques sont stockées séparément dans la mémoire, de sorte que lorsque vous créez une nouvelle instance de votre structure, cette instance ne portent pas de numéros de magie dans l'instance de l'emplacement de la mémoire, de sorte que votre utilisation de
writeToFile
ne fonctionnera pas comme prévu.OriginalL'auteur loganfsmyth