Question

I ai une fonction qui génère un octet de contrôle CRC sur la base du contenu d'un paquet problème est de traduire la fonction de C ++ à C #

Le code C de:

unsigned char GenerateCheckByte( char* packet, int length, unsigned long seed )
{
if( !packet ) return 0;
unsigned long checksum = 0xFFFFFFFF;
length &= 0x7FFF;
char* ptr = packet;
unsigned long moddedseed = seed << 8;
for( int i = 0; i < length; i++ )
    checksum = ( checksum >> 8 ) ^ table[moddedseed + ( ( *(ptr++) ^ checksum ) & 0xFF )];
unsigned char result = ( (checksum>>24)&0xFF ) + ( (checksum>>8)&0xFF ) + ( (checksum>>16)&0xFF ) + ( checksum&0xFF );
return result;
}

le paquet char * (paquet) peut également être défini comme LPBYTE, l'idée est que la valeur attribuée à * est attribué à * ptr et que vous voyez * ptr increases.Meaning un tableau d'octets est passé et en augmentant la valeur du pointeur, il va à l'octet suivant.

J'ai essayé de le faire en C # et beaucoup fois.Après échouais un travail acharné que j'ai compris un peu de code, mais je ne peux pas l'exécuter:

code C #

    public static unsafe byte GenerateCheckByte(byte *packet, int length, UInt32 seed )
    {
        if (*packet == 0)
        return 0;
        UInt32 checksum = 0xFFFFFFFF;
        length &= 0x7FFF;
        byte *ptr = packet;
        UInt32 moddedseed = seed << 8;
        for (int i = 0; i < length; i++)
            checksum = ( checksum >> 8 ) ^ Table.table[moddedseed + ( ( *(ptr++) ^ checksum ) & 0xFF )];
        byte result = (byte)(( (checksum>>24)&0xFF ) + ( (checksum>>8)&0xFF ) + ( (checksum>>16)&0xFF ) + ( checksum&0xFF ));
        return result;
    }

Il ne semble pas si mal que ça, mais je ne peux pas l'appeler

  unsafe
  {
      packetBuffer[5] = Functions.GenerateCheckByte(&packetBuffer[0], 18, packet.seedCRC);
  }

erreur: « Vous ne pouvez prendre l'adresse d'une expression non fixée à l'intérieur d'une déclaration fixe initialiseur »

S'il vous plaît noter

packetbuffer dans les deux C ++ et C # application est byte [] packetBuffer = new byte [18];

Était-ce utile?

La solution

Vous pouvez faire la méthode accepter un tableau d'octets:

public static unsafe byte GenerateCheckByte(byte[] packetArray, int length, UInt32 seed)
{
    fixed(byte *packet = packetArray)
    {
        ... etc
    }
}

Il est préférable de garder les choses dangereuses caché autant que possible par des interfaces gérées.

Alors appelle, il serait facile:

packetBuffer[5] = Functions.GenerateCheckByte(packetBuffer, 18, ...

En fait, il serait préférable d'écrire GenerateCheckByte pour fonctionner sur un tableau de toute façon, au lieu de plonger dans les techniques de unsafe:

public static unsafe byte GenerateCheckByte(byte[] packet, int length, UInt32 seed )
{
    if (packet == null)
        throw new ArgumentNullException("packet"); // the right way in C#

    UInt32 checksum = 0xFFFFFFFF;
    length &= 0x7FFF;

    UInt32 moddedseed = seed << 8;
    for (int i = 0; i < length; i++)
        checksum = ( checksum >> 8 ) ^ Table.table[moddedseed + ( ( packet[i] ^ checksum ) & 0xFF )];
    byte result = (byte)(( (checksum>>24)&0xFF ) + ( (checksum>>8)&0xFF ) + ( (checksum>>16)&0xFF ) + ( checksum&0xFF ));
    return result;
}

Ecrire la plus simple, la plus sûre mise en œuvre, vous pouvez, et ne plaisante pas avec des pointeurs si vous trouvez un goulot d'étranglement dans le profilage.

Êtes-vous juste traduisez beaucoup d'exister C / C ++ en C #? Il y a peu d'intérêt à faire que si vous obtenez une nouvelle sécurité / maintenabilité de celui-ci. :)

Autres conseils

Vous ne devriez pas avoir à utiliser le code dangereux du tout. Si vous envoyez dans un tableau d'octets à la fonction, il peut y accéder sans utiliser des pointeurs.

Je ne l'ai pas testé le code, mais il devrait être quelque chose comme ceci:

byte GenerateCheckByte(byte[] packet, ulong seed) {
    if (packet == null) return 0;
    int length = packet.Length & 0x7FFF;
    ulong checksum = 0xFFFFFFFF;
    ulong moddedseed = seed << 8;
    for (int i = 0; i < length; i++) {
            checksum = (checksum >> 8) ^ table[moddedseed + ((packet[i] ^ checksum) & 0xFF)];
    }
    return (byte)(
        ((checksum >> 24) & 0xFF) +
        ((checksum >> 16) & 0xFF) +
        ((checksum >> 8) & 0xFF) +
        (checksum & 0xFF)
    );
}

Vous devez « pin » du tableau d'octets en mémoire pour l'utiliser comme un octet *.

byte checksum; 
fixed(byte* pPacketBuffer = packetBuffer)
{
    checksum = Functions.GenerateCheckByte(pPacketBuffer, 18, packet.seedCRC) 
}
packetBuffer[5] = checksum 

Références:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top