web-dev-qa-db-fra.com

Conversion de struct en octet et de retour en struct

Je travaille actuellement avec Arduino Uno s, 9DOF et XBee s, et j'essayais de créer une structure qui pourrait être envoyée en série, octet par octet, et puis reconstruit en une structure.

Jusqu'à présent, j'ai le code suivant:

struct AMG_ANGLES {
    float yaw;
    float pitch;
    float roll;
};

int main() {
    AMG_ANGLES struct_data;

    struct_data.yaw = 87.96;
    struct_data.pitch = -114.58;
    struct_data.roll = 100.50;

    char* data = new char[sizeof(struct_data)];

    for(unsigned int i = 0; i<sizeof(struct_data); i++){
        // cout << (char*)(&struct_data+i) << endl;
        data[i] = (char*)(&struct_data+i); //Store the bytes of the struct to an array.
    }

    AMG_ANGLES* tmp = (AMG_ANGLES*)data; //Re-make the struct
    cout << tmp.yaw; //Display the yaw to see if it's correct.
}

Source: http://codepad.org/xMgxGY9Q

Ce code ne semble pas fonctionner et je ne suis pas sûr de ce que je fais mal.

Comment résoudre ce problème?

21
Steven10172

Il semble que j'ai résolu mon problème avec le code suivant.

struct AMG_ANGLES {
    float yaw;
    float pitch;
    float roll;
};

int main() {
    AMG_ANGLES struct_data;

    struct_data.yaw = 87.96;
    struct_data.pitch = -114.58;
    struct_data.roll = 100.50;

    //Sending Side
    char b[sizeof(struct_data)];
    memcpy(b, &struct_data, sizeof(struct_data));

    //Receiving Side
    AMG_ANGLES tmp; //Re-make the struct
    memcpy(&tmp, b, sizeof(tmp));
    cout << tmp.yaw; //Display the yaw to see if it's correct
}

AVERTISSEMENT: ce code ne fonctionnera que si l'envoi et la réception utilisent la même architecture endian .

30
Steven10172

Vous faites les choses dans le mauvais ordre, l'expression

&struct_data+i

prend l'adresse de struct_data et l'augmente de ifois la taille de la structure.

Essayez plutôt ceci:

*((char *) &struct_data + i)

Cela convertit l'adresse de struct_data à un char * et alors ajoute l'index, puis utilise l'opérateur de déréférence (unaire *) pour obtenir le "char" à cette adresse.

7

Utilisez toujours les structures de données au maximum.

union AMG_ANGLES {
  struct {
    float yaw;
    float pitch;
    float roll;
  }data;
  char  size8[3*8];
  int   size32[3*4];
  float size64[3*1];
};
5
CharLess
for(unsigned int i = 0; i<sizeof(struct_data); i++){
    // +i has to be outside of the parentheses in order to increment the address
    // by the size of a char. Otherwise you would increment by the size of
    // struct_data. You also have to dereference the whole thing, or you will
    // assign an address to data[i]
    data[i] = *((char*)(&struct_data) + i); 
}

AMG_ANGLES* tmp = (AMG_ANGLES*)data; //Re-Make the struct
//tmp is a pointer so you have to use -> which is shorthand for (*tmp).yaw
cout << tmp->yaw; 
}
1
jtepe