0
votes

Qu'est-ce que cela signifie la déclaration C suivante? ((int *) & var)

J'ai le code suivant dans C pour calculer un CRC16-USB pour certains flux de données: xxx pré>

croc16_table em> est une matrice de 2 valeurs hexagonales de 2 Les octets (comme 0xaff3), et Data ​​em> sont une matrice de valeurs hexagonales de 1 octet (comme 0xa3) représentant le flux de données (AQCUIRELIÉ par d'autres moyens). Taille em> est la longueur de la matrice Data ​​em>. p>

Je veux reproduire ce morceau de code dans Python, mais je ne sais pas que cette déclaration Moyens: P>

index = ((uint8_t*) & init)[1] ^ *data++;


2 commentaires

Il jette l'adresse d'un uint16_t variable pour être un pointeur sur uint8_t .


Il s'agit de deuxième octet de init et de xoriser avec valeur pointée par data , augmentation des données après cela.


3 Réponses :


-1
votes

L'intention de l'index = ((uint8_t *) & init) [1] ^ * Data ++; L'instruction est sur XOR les huit bits élevés de init avec le Next octet de données (et d'incrémenter `données). Malheureusement, il est écrit mal.

Dans l'énoncé Index = ((uint8_t *) & init) [1] ^ * Data ++; :

  • & init prend l'adresse de init (qui a été défini avec uint16_t init = crcbase; ).
  • (uint8_t *) convertit cette adresse à un pointeur vers uint8_t . L'utilisation ultérieure de ce pointeur nécessite que uint8_t soit un type de caractère dans la mise en oeuvre C, qui est probable mais n'est pas garanti par la norme C.
  • Appliquer [1] sur ce pointeur récupère l'octet suivant au-delà de l'endroit où le pointeur pointe. Le fait que la deuxième ligne utilise init << 8 , ce qui entraîne une valeur uniquement dépendante du * ** huit bits de init , suggère que l'intention de cette La première ligne consistait à récupérer les huit bits de init .

    Cependant, la norme C n'exige pas que les octets d'un uint16_t soient dans une commande particulière, il n'est donc pas assuré que l'utilisation de [1] va chercher les bits souhaités. Et il n'est pas nécessaire; Utilisation de init >> 8 à la place de ((uint8_t *) & init) [1] fournirait les bits souhaités.

    Ainsi, le code aurait pu être simplement: xxx


0 commentaires

1
votes

init a le type uint16_t , donc l'expression expression & init a type "pointeur sur uint16_t < / code> "ou uint16_t * . L'expression (uint8_t *) & init signifie "Obtenez l'adresse de init , mais traitez-la comme l'adresse d'un uint8_t objet, plutôt que uint16_t objet ".

Cette adresse est ensuite utilisée avec un opérateur d'indice - ((uint8_t *) & init) [1] , qui est essentiellement équivalent à" traiter < Code> init comme une matrice de deux uint8_t objets et donnez-moi la valeur du deuxième élément dans ce tableau ".

graphiquement: xxx

SO, fondamentalement, vous saisissez les 8 bits inférieurs de init , Ça avec La valeur de l'octet actuel du message d'entrée, puis avancez data pour pointer sur l'octet suivant du message d'entrée.


0 commentaires

1
votes

J'ai trouvé une solution pour mon problème, avec le code suivant:

def calculateCRC16(data):
    init = 0xFFFF
    for byte in data:
        index = (init >> 8) ^ byte
        init = ((init << 8) ^ crc16_table[index]) & 0xFFFF
    return init


0 commentaires