I have a function that generates a CRC check byte based on the content of any packet.The problem is in translating the function from C++ to C#
C++ code:
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; }
the char*(packet) can also be defined as LPBYTE,the idea is that the value assigned to *packet is assigned to *ptr and as you see *ptr increases.Meaning a byte array is passed in and by increasing the value of the pointer it goes to the next byte.
I tried to do it in C# and failed many times.After some hard work I figured out some code,but i can’t execute it 😕
C# code
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; }
It doesn’t look that bad,but I can’t call it
unsafe { packetBuffer[5] = Functions.GenerateCheckByte(&packetBuffer[0], 18, packet.seedCRC); }
error: ‘You can only take the address of an unfixed expression inside of a fixed statement initializer’
Please note
packetbuffer in both C++ and C# application is byte[] packetBuffer = new byte[18];
You could make the method accept a byte array:
It’s better to keep the unsafe stuff hidden away as much as possible behind managed interfaces.
Then calling it would be easy:
In fact, it would be better to write
GenerateCheckByteto operate on an array anyway, instead of delving intounsafetechniques:Write the simplest, safest implementation you can, and only mess with pointers if you find a bottleneck in profiling.
Are you just translating a lot of existing C/C++ into C#? There’s little point doing that unless you get some new safety/maintainability from it. 🙂