Como atribuir byte [] como um ponteiro em C #
Pergunta
Eu tenho uma função que gera um byte de verificação CRC com base no conteúdo de qualquer problema packet.The é em traduzir a função de C ++ para C #
código C ++:
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;
}
o caractere * (pacote) também pode ser definida como LPBYTE, a idéia é que o valor atribuído a * pacote é atribuído a * ptr e como você vê ptr * increases.Meaning uma matriz de bytes é passado e aumentando a valor do ponteiro ele vai para o próximo byte.
Eu tentei fazê-lo em C # e falhou muitos times.After algum trabalho duro que eu descobri algum código, mas não consigo executá-lo:?
código 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;
}
Não parece tão ruim, mas eu não posso chamá-lo
unsafe
{
packetBuffer[5] = Functions.GenerateCheckByte(&packetBuffer[0], 18, packet.seedCRC);
}
erro: "Você só pode obter o endereço de um interior expressão unfixed de um inicializador declaração fixo"
Por favor nota ??strong>
packetbuffer em C ++ e aplicação C # é byte [] packetBuffer = new byte [18];
Solução
Você poderia fazer o método de aceitar uma matriz de bytes:
public static unsafe byte GenerateCheckByte(byte[] packetArray, int length, UInt32 seed)
{
fixed(byte *packet = packetArray)
{
... etc
}
}
É melhor para manter as coisas inseguras escondido tanto quanto as interfaces gerenciadas possível trás.
Em seguida, chamando seria fácil:
packetBuffer[5] = Functions.GenerateCheckByte(packetBuffer, 18, ...
Na verdade, seria melhor escrever GenerateCheckByte
para operar em uma matriz de qualquer maneira, em vez de se aprofundar em técnicas 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;
}
Escrever o mais simples implementação, o mais seguro possível, e só mexer com ponteiros se você encontrar um gargalo em perfis.
Você está apenas traduzir um monte de existente C / C ++ em C #? Há pouco ponto de fazer isso a menos que você obter alguma nova segurança / manutenção dele. :)
Outras dicas
Você não deveria ter que usar o código inseguro em tudo. Se você enviar uma matriz de bytes para a função, pode acessá-lo sem o uso de ponteiros.
Eu não testei o código, mas deve ser algo como isto:
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)
);
}
Você precisa 'pin' a matriz de bytes na memória para usá-lo como um byte *.
byte checksum;
fixed(byte* pPacketBuffer = packetBuffer)
{
checksum = Functions.GenerateCheckByte(pPacketBuffer, 18, packet.seedCRC)
}
packetBuffer[5] = checksum
Referências: