我有一个功能,产生CRC签字节根据上述内容的任何分组。问题是在将功能,从C++C#

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;
}

char*(分组)也可以被定义为LPBYTE,这个想法是值分配*分组是分配给*ptr和你见*ptr增加。这意味着一个字节列传递和通过增加价值的指针转到下一个字节。

我试图做到这一点在C#和失败的许多倍。后一些艰苦的工作我想通了一些代码,但是我不能执行它:?

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;
    }

它看起来并不坏,但我不能叫它

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

错误:"你只能把地址的一个不固定的表达的内的一个固定的声明的初始化"

请注意

packetbuffer在两C++和C#应用程序是字节[]packetBuffer=new字节[18个];

有帮助吗?

解决方案

您可以使该方法接受一个字节数组:

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

这是更好地保持不安全的东西隐藏起来,尽可能多地后管理界面。

然后调用它会很容易:

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

在实际上,这将是更好写GenerateCheckByte反正阵列上操作,而不是钻研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;
}

写最简单,最安全的实现就可以了,用指针只烂摊子,如果你发现在分析的瓶颈。

您刚刚翻译了很多现有的C / C ++到C#的?有小点,这样做,除非你从它那里得到一些新的安全性/可维护性。 :)

其他提示

您不应该在所有使用不安全的代码。如果在一个字节数组的函数发送时,它可以访问它不使用的指针。

我还没有测试的代码,但它应该是这样的:

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)
    );
}

你需要别的字节列入存储器使用它作为一个字节*.

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

参考文献:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top